Merge branch 'master' of ssh://gitlab-fnwi.uva.nl:1337/11166932/TheReturnOfTheMyHyvesBookPlus into niels-notulen
2
.gitignore
vendored
@@ -49,7 +49,7 @@ captures/
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
|
|
||||||
# Google Services (e.g. APIs or Firebase)
|
# Google Services (e.g. APIs or Firebase)
|
||||||
google-services.json
|
# google-services.json
|
||||||
|
|
||||||
# Freeline
|
# Freeline
|
||||||
freeline.py
|
freeline.py
|
||||||
|
|||||||
9
app/MyHyvesBookPlusStagram/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/libraries
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
1
app/MyHyvesBookPlusStagram/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
45
app/MyHyvesBookPlusStagram/app/build.gradle
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 25
|
||||||
|
buildToolsVersion "25.0.3"
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "nl.myhyvesbookplus.tagram"
|
||||||
|
minSdkVersion 21
|
||||||
|
targetSdkVersion 25
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||||
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
|
})
|
||||||
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
|
compile 'com.android.support:design:25.3.1'
|
||||||
|
compile 'com.google.firebase:firebase-database:10.0.1'
|
||||||
|
compile 'com.google.firebase:firebase-auth:10.0.1'
|
||||||
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
compile 'com.android.support:support-v4:25.3.1'
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
42
app/MyHyvesBookPlusStagram/app/google-services.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "1078950034345",
|
||||||
|
"firebase_url": "https://myhyvesbookplus.firebaseio.com",
|
||||||
|
"project_id": "myhyvesbookplus",
|
||||||
|
"storage_bucket": "myhyvesbookplus.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:1078950034345:android:9cf50e62584e4051",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "nl.myhyvesbookplus.tagram"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "1078950034345-dmsbu0066sfqgqthn2mldlauvdef98u9.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyBZdJPt0mdckSXM-hlcfAhdrh3pX76m5Cw"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"analytics_service": {
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"appinvite_service": {
|
||||||
|
"status": 1,
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
},
|
||||||
|
"ads_service": {
|
||||||
|
"status": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
25
app/MyHyvesBookPlusStagram/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /Users/marijnjansen/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
26
app/MyHyvesBookPlusStagram/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="nl.myhyvesbookplus.tagram">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".LoginActivity">
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Activities that contain this fragment must implement the
|
||||||
|
* {@link CameraFragment.OnFragmentInteractionListener} interface
|
||||||
|
* to handle interaction events.
|
||||||
|
* Use the {@link CameraFragment#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
public class CameraFragment extends Fragment {
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
private static final String ARG_PARAM1 = "param1";
|
||||||
|
private static final String ARG_PARAM2 = "param2";
|
||||||
|
|
||||||
|
// TODO: Rename and change types of parameters
|
||||||
|
private String mParam1;
|
||||||
|
private String mParam2;
|
||||||
|
|
||||||
|
private OnFragmentInteractionListener mListener;
|
||||||
|
|
||||||
|
public CameraFragment() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this factory method to create a new instance of
|
||||||
|
* this fragment using the provided parameters.
|
||||||
|
*
|
||||||
|
* @param param1 Parameter 1.
|
||||||
|
* @param param2 Parameter 2.
|
||||||
|
* @return A new instance of fragment CameraFragment.
|
||||||
|
*/
|
||||||
|
// TODO: Rename and change types and number of parameters
|
||||||
|
public static CameraFragment newInstance(String param1, String param2) {
|
||||||
|
CameraFragment fragment = new CameraFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ARG_PARAM1, param1);
|
||||||
|
args.putString(ARG_PARAM2, param2);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
mParam1 = getArguments().getString(ARG_PARAM1);
|
||||||
|
mParam2 = getArguments().getString(ARG_PARAM2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
return inflater.inflate(R.layout.fragment_camera, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Rename method, update argument and hook method into UI event
|
||||||
|
public void onButtonPressed(Uri uri) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onFragmentInteraction(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
if (context instanceof OnFragmentInteractionListener) {
|
||||||
|
mListener = (OnFragmentInteractionListener) context;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(context.toString()
|
||||||
|
+ " must implement OnFragmentInteractionListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface must be implemented by activities that contain this
|
||||||
|
* fragment to allow an interaction in this fragment to be communicated
|
||||||
|
* to the activity and potentially other fragments contained in that
|
||||||
|
* activity.
|
||||||
|
* <p>
|
||||||
|
* See the Android Training lesson <a href=
|
||||||
|
* "http://developer.android.com/training/basics/fragments/communicating.html"
|
||||||
|
* >Communicating with Other Fragments</a> for more information.
|
||||||
|
*/
|
||||||
|
public interface OnFragmentInteractionListener {
|
||||||
|
// TODO: Update argument type and name
|
||||||
|
void onFragmentInteraction(Uri uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.auth.AuthResult;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.FirebaseUser;
|
||||||
|
import com.google.firebase.auth.UserProfileChangeRequest;
|
||||||
|
|
||||||
|
public class LoginActivity extends AppCompatActivity {
|
||||||
|
public static final String TAG = "Login";
|
||||||
|
|
||||||
|
/// Views ///
|
||||||
|
|
||||||
|
protected EditText emailField, usernameField, passwordField;
|
||||||
|
protected TextView passwordConfirmField, passwordConfirmLabel, usernameLabel;
|
||||||
|
protected Button registerButton, backToLoginButton, goToRegisterButton, logInButton;
|
||||||
|
|
||||||
|
protected FirebaseAuth mAuth;
|
||||||
|
|
||||||
|
/// Setup ///
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(nl.myhyvesbookplus.tagram.R.layout.activity_login);
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
|
findViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns all views.
|
||||||
|
*/
|
||||||
|
protected void findViews() {
|
||||||
|
passwordConfirmLabel = (TextView) findViewById(R.id.confirm_password_label);
|
||||||
|
usernameLabel = (TextView) findViewById(R.id.username_label);
|
||||||
|
|
||||||
|
registerButton = (Button) findViewById(R.id.register_button);
|
||||||
|
backToLoginButton = (Button) findViewById(R.id.back_to_login_button);
|
||||||
|
goToRegisterButton = (Button) findViewById(R.id.go_to_register_button);
|
||||||
|
logInButton = (Button) findViewById(R.id.login_button);
|
||||||
|
|
||||||
|
passwordConfirmField = (EditText) findViewById(R.id.confirm_password_field);
|
||||||
|
usernameField = (EditText) findViewById(R.id.username);
|
||||||
|
passwordField = (EditText) findViewById(R.id.password);
|
||||||
|
emailField = (EditText) findViewById(R.id.email);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// OnClick ///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the logon action.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void logInOnClick(View view) {
|
||||||
|
String emailSting = emailField.getText().toString();
|
||||||
|
String passwordSting = passwordField.getText().toString();
|
||||||
|
|
||||||
|
logIn(emailSting, passwordSting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the register action.
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void registerOnClick(View view) {
|
||||||
|
Log.d(TAG, "registerOnClick: ");
|
||||||
|
|
||||||
|
if (passwordField.getText().toString().equals(passwordConfirmField.getText().toString())) {
|
||||||
|
registerUser(emailField.getText().toString(), passwordField.getText().toString());
|
||||||
|
} else {
|
||||||
|
Toast.makeText(LoginActivity.this, "Passwords do not match",
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
Log.d(TAG, "registerOnClick: Passwords do not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UI-changes ///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the Activity for registering.
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void goToRegisterOnClick(View view) {
|
||||||
|
passwordConfirmField.setVisibility(View.VISIBLE);
|
||||||
|
passwordConfirmLabel.setVisibility(View.VISIBLE);
|
||||||
|
registerButton.setVisibility(View.VISIBLE);
|
||||||
|
backToLoginButton.setVisibility(View.VISIBLE);
|
||||||
|
usernameField.setVisibility(View.VISIBLE);
|
||||||
|
usernameLabel.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
goToRegisterButton.setVisibility(View.GONE);
|
||||||
|
logInButton.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the Activity for logging in.
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void backToLoginOnClick(View view) {
|
||||||
|
passwordConfirmField.setVisibility(View.GONE);
|
||||||
|
passwordConfirmLabel.setVisibility(View.GONE);
|
||||||
|
registerButton.setVisibility(View.GONE);
|
||||||
|
backToLoginButton.setVisibility(View.GONE);
|
||||||
|
usernameField.setVisibility(View.GONE);
|
||||||
|
usernameLabel.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
goToRegisterButton.setVisibility(View.VISIBLE);
|
||||||
|
logInButton.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs intend to Main screen.
|
||||||
|
*/
|
||||||
|
protected void goToMainScreen() {
|
||||||
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
this.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FireBase ///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the actual login action.
|
||||||
|
* @param emailSting email address
|
||||||
|
* @param passwordSting the entered password
|
||||||
|
*/
|
||||||
|
protected void logIn(String emailSting, String passwordSting) {
|
||||||
|
mAuth.signInWithEmailAndPassword(emailSting, passwordSting)
|
||||||
|
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
// Sign in success, update UI with the signed-in user's information
|
||||||
|
Log.d(TAG, "signInWithEmail:success");
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
Log.d(TAG, "onComplete: isVerified " + user.isEmailVerified());
|
||||||
|
user.isEmailVerified();
|
||||||
|
goToMainScreen();
|
||||||
|
} else {
|
||||||
|
// If sign in fails, display a message to the user.
|
||||||
|
Log.w(TAG, "signInWithEmail:failure", task.getException());
|
||||||
|
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the actual register action
|
||||||
|
* @param email Users email address
|
||||||
|
* @param password the entered password
|
||||||
|
*/
|
||||||
|
protected void registerUser(String email, String password) {
|
||||||
|
mAuth.createUserWithEmailAndPassword(email, password)
|
||||||
|
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
// Sign in success, update UI with the signed-in user's information
|
||||||
|
Log.d(TAG, "createUserWithEmail:success");
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
updateUserInfo(user);
|
||||||
|
goToMainScreen();
|
||||||
|
} else {
|
||||||
|
// If sign in fails, display a message to the user.
|
||||||
|
Log.w(TAG, "createUserWithEmail:failure", task.getException());
|
||||||
|
if (task.getException() != null) {
|
||||||
|
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the Username to Firebase
|
||||||
|
* @param user The User object that needs to be updated
|
||||||
|
*/
|
||||||
|
protected void updateUserInfo(final FirebaseUser user) {
|
||||||
|
UserProfileChangeRequest request = new UserProfileChangeRequest.Builder()
|
||||||
|
.setDisplayName(usernameField.getText().toString())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
user.updateProfile(request)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<Void> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Log.d(TAG, "User profile updated.");
|
||||||
|
}
|
||||||
|
sendConfirmEmail(user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a confirm email
|
||||||
|
* @param user The User object which the mail needs to be send to
|
||||||
|
*/
|
||||||
|
protected void sendConfirmEmail(FirebaseUser user) {
|
||||||
|
user.sendEmailVerification()
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<Void> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Log.d(TAG, "Email sent.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.app.FragmentManager;
|
||||||
|
import android.app.FragmentTransaction;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.design.widget.BottomNavigationView;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity implements CameraFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener, TimelineFragment.OnFragmentInteractionListener {
|
||||||
|
final static private String TAG = "MainScreen";
|
||||||
|
|
||||||
|
FirebaseAuth mAuth;
|
||||||
|
|
||||||
|
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
|
||||||
|
= new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case nl.myhyvesbookplus.tagram.R.id.navigation_timeline:
|
||||||
|
Log.d(TAG, "onNavigationItemSelected: Timeline");
|
||||||
|
TimelineFragment timeline = new TimelineFragment();
|
||||||
|
transaction.replace(R.id.content, timeline);
|
||||||
|
transaction.addToBackStack(null);
|
||||||
|
transaction.commit();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case nl.myhyvesbookplus.tagram.R.id.navigation_camera:
|
||||||
|
Log.d(TAG, "onNavigationItemSelected: Camera");
|
||||||
|
CameraFragment camera = new CameraFragment();
|
||||||
|
transaction.replace(R.id.content, camera);
|
||||||
|
transaction.addToBackStack(null);
|
||||||
|
transaction.commit();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case nl.myhyvesbookplus.tagram.R.id.navigation_profile:
|
||||||
|
Log.d(TAG, "onNavigationItemSelected: Profile");
|
||||||
|
ProfileFragment profile = new ProfileFragment();
|
||||||
|
transaction.replace(R.id.content, profile);
|
||||||
|
transaction.addToBackStack(null);
|
||||||
|
transaction.commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(nl.myhyvesbookplus.tagram.R.layout.activity_main);
|
||||||
|
|
||||||
|
BottomNavigationView navigation = (BottomNavigationView) findViewById(nl.myhyvesbookplus.tagram.R.id.navigation);
|
||||||
|
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
|
||||||
|
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
if (mAuth.getCurrentUser() == null) {
|
||||||
|
goToLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineFragment fragment = new TimelineFragment();
|
||||||
|
|
||||||
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
|
transaction.replace(R.id.content, fragment);
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFragmentInteraction(Uri uri) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logOutOnClick(View view) {
|
||||||
|
FirebaseAuth.getInstance().signOut();
|
||||||
|
goToLogin();
|
||||||
|
this.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void goToLogin() {
|
||||||
|
Intent goToLogIn = new Intent(this, LoginActivity.class);
|
||||||
|
startActivity(goToLogIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Activities that contain this fragment must implement the
|
||||||
|
* {@link ProfileFragment.OnFragmentInteractionListener} interface
|
||||||
|
* to handle interaction events.
|
||||||
|
* Use the {@link ProfileFragment#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
public class ProfileFragment extends Fragment {
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
private static final String ARG_PARAM1 = "param1";
|
||||||
|
private static final String ARG_PARAM2 = "param2";
|
||||||
|
|
||||||
|
// TODO: Rename and change types of parameters
|
||||||
|
private String mParam1;
|
||||||
|
private String mParam2;
|
||||||
|
|
||||||
|
private OnFragmentInteractionListener mListener;
|
||||||
|
|
||||||
|
public ProfileFragment() {
|
||||||
|
// 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 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
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
mParam1 = getArguments().getString(ARG_PARAM1);
|
||||||
|
mParam2 = getArguments().getString(ARG_PARAM2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
return inflater.inflate(R.layout.fragment_profile, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Rename method, update argument and hook method into UI event
|
||||||
|
public void onButtonPressed(Uri uri) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onFragmentInteraction(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
if (context instanceof OnFragmentInteractionListener) {
|
||||||
|
mListener = (OnFragmentInteractionListener) context;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(context.toString()
|
||||||
|
+ " must implement OnFragmentInteractionListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface must be implemented by activities that contain this
|
||||||
|
* fragment to allow an interaction in this fragment to be communicated
|
||||||
|
* to the activity and potentially other fragments contained in that
|
||||||
|
* activity.
|
||||||
|
* <p>
|
||||||
|
* See the Android Training lesson <a href=
|
||||||
|
* "http://developer.android.com/training/basics/fragments/communicating.html"
|
||||||
|
* >Communicating with Other Fragments</a> for more information.
|
||||||
|
*/
|
||||||
|
public interface OnFragmentInteractionListener {
|
||||||
|
// TODO: Update argument type and name
|
||||||
|
void onFragmentInteraction(Uri uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Activities that contain this fragment must implement the
|
||||||
|
* {@link TimelineFragment.OnFragmentInteractionListener} interface
|
||||||
|
* to handle interaction events.
|
||||||
|
* Use the {@link TimelineFragment#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
public class TimelineFragment extends Fragment {
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
private static final String ARG_PARAM1 = "param1";
|
||||||
|
private static final String ARG_PARAM2 = "param2";
|
||||||
|
|
||||||
|
// TODO: Rename and change types of parameters
|
||||||
|
private String mParam1;
|
||||||
|
private String mParam2;
|
||||||
|
|
||||||
|
private OnFragmentInteractionListener mListener;
|
||||||
|
|
||||||
|
public TimelineFragment() {
|
||||||
|
// 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 TimelineFragment.
|
||||||
|
*/
|
||||||
|
// TODO: Rename and change types and number of parameters
|
||||||
|
public static TimelineFragment newInstance(String param1, String param2) {
|
||||||
|
TimelineFragment fragment = new TimelineFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ARG_PARAM1, param1);
|
||||||
|
args.putString(ARG_PARAM2, param2);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
mParam1 = getArguments().getString(ARG_PARAM1);
|
||||||
|
mParam2 = getArguments().getString(ARG_PARAM2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
return inflater.inflate(R.layout.fragment_timeline, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Rename method, update argument and hook method into UI event
|
||||||
|
public void onButtonPressed(Uri uri) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onFragmentInteraction(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
if (context instanceof OnFragmentInteractionListener) {
|
||||||
|
mListener = (OnFragmentInteractionListener) context;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(context.toString()
|
||||||
|
+ " must implement OnFragmentInteractionListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface must be implemented by activities that contain this
|
||||||
|
* fragment to allow an interaction in this fragment to be communicated
|
||||||
|
* to the activity and potentially other fragments contained in that
|
||||||
|
* activity.
|
||||||
|
* <p>
|
||||||
|
* See the Android Training lesson <a href=
|
||||||
|
* "http://developer.android.com/training/basics/fragments/communicating.html"
|
||||||
|
* >Communicating with Other Fragments</a> for more information.
|
||||||
|
*/
|
||||||
|
public interface OnFragmentInteractionListener {
|
||||||
|
// TODO: Update argument type and name
|
||||||
|
void onFragmentInteraction(Uri uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<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="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<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="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<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>
|
||||||
BIN
app/MyHyvesBookPlusStagram/app/src/main/res/drawable/logo.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"--><!--xmlns:app="http://schemas.android.com/apk/res-auto"--><!--xmlns:tools="http://schemas.android.com/tools"--><!--android:layout_width="match_parent"--><!--android:layout_height="match_parent"--><!--tools:context="nl.myhyvesbookplus.tagram.LoginActivity">-->
|
||||||
|
|
||||||
|
<!--</android.support.constraint.ConstraintLayout>-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
tools:context=".LoginActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:src="@drawable/logo" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:labelFor="@+id/email"
|
||||||
|
android:text="@string/email" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/email"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textEmailAddress" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/username_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:labelFor="@+id/username"
|
||||||
|
android:text="@string/username"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/username"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="text"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:labelFor="@+id/password"
|
||||||
|
android:text="@string/password" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textPassword" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/confirm_password_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/confirm_password"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/confirm_password_field"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/login_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:onClick="logInOnClick"
|
||||||
|
android:text="@string/login_button" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/go_to_register_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:onClick="goToRegisterOnClick"
|
||||||
|
android:text="@string/register" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/register_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:onClick="registerOnClick"
|
||||||
|
android:text="@string/register"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/back_to_login_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:onClick="backToLoginOnClick"
|
||||||
|
android:text="@string/back_to_login"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout 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:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context="nl.myhyvesbookplus.tagram.MainActivity">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:padding="16dp">
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.BottomNavigationView
|
||||||
|
android:id="@+id/navigation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="?android:attr/windowBackground"
|
||||||
|
app:menu="@menu/navigation" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<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.CameraFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/hello_camera" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="logOutOnClick"
|
||||||
|
android:text="LogOut" />
|
||||||
|
</LinearLayout>
|
||||||
|
<!-- TODO: Update blank fragment layout -->
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<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,13 @@
|
|||||||
|
<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.TimelineFragment">
|
||||||
|
|
||||||
|
<!-- 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,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/navigation_timeline"
|
||||||
|
android:icon="@drawable/ic_home_black_24dp"
|
||||||
|
android:title="@string/title_home" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/navigation_camera"
|
||||||
|
android:icon="@drawable/ic_dashboard_black_24dp"
|
||||||
|
android:title="@string/title_dashboard" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/navigation_profile"
|
||||||
|
android:icon="@drawable/ic_notifications_black_24dp"
|
||||||
|
android:title="@string/title_notifications" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">MyHyvesBookPlusTagram</string>
|
||||||
|
<string name="back_to_login">terug naar Login</string>
|
||||||
|
<string name="confirm_password">Bevestig wachtwoord</string>
|
||||||
|
<string name="email">Email</string>
|
||||||
|
<string name="login_button">Login</string>
|
||||||
|
<string name="password">Wachtwoord</string>
|
||||||
|
<string name="register">Registreer</string>
|
||||||
|
<string name="title_dashboard">Camera</string>
|
||||||
|
<string name="title_home">Tijdlijn</string>
|
||||||
|
<string name="title_notifications">Profiel</string>
|
||||||
|
<string name="username">Gebruikersnaam</string>
|
||||||
|
<string name="confirm_password_hint">bevestig wachtwoord</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#fbbf2d</color>
|
||||||
|
<color name="colorPrimaryDark">#ffa70f</color>
|
||||||
|
<color name="colorAccent">#4CAF50</color>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">MyHyvesBookPlusTagram</string>
|
||||||
|
<string name="title_home">Timeline</string>
|
||||||
|
<string name="title_dashboard">Camera</string>
|
||||||
|
<string name="title_notifications">Profile</string>
|
||||||
|
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="username">Username</string>
|
||||||
|
<string name="password">Password</string>
|
||||||
|
<string name="confirm_password">Confirm Password</string>
|
||||||
|
<string name="confirm_password_hint">confirm password</string>
|
||||||
|
<string name="login_button">Login</string>
|
||||||
|
<string name="register">Register</string>
|
||||||
|
<string name="back_to_login">back to Login</string>
|
||||||
|
<string name="email">Email</string>
|
||||||
|
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
|
<string name="hello_camera">Hello Camera</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
24
app/MyHyvesBookPlusStagram/build.gradle
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
classpath 'com.google.gms:google-services:3.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
17
app/MyHyvesBookPlusStagram/gradle.properties
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
BIN
app/MyHyvesBookPlusStagram/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
app/MyHyvesBookPlusStagram/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Tue Jun 13 12:22:59 CEST 2017
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||||
160
app/MyHyvesBookPlusStagram/gradlew
vendored
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
90
app/MyHyvesBookPlusStagram/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
1
app/MyHyvesBookPlusStagram/settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
BIN
projectplan/MyHyvesBookPlusTagramProjectPlan.pdf
Normal file
203
projectplan/MyHyvesBookPlusTagramProjectPlan.tex
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% LATEX-TEMPLATE PROJECTPLAN
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% Voor informatie over het projectplan, zie
|
||||||
|
% http://practicumav.nl/project/projectplan.html
|
||||||
|
% Voor readme en meest recente versie van het template, zie
|
||||||
|
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% PACKAGES EN DOCUMENT CONFIGURATIE
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\documentclass{uva-inf-article}
|
||||||
|
\usepackage[dutch]{babel}
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% GEGEVENS VOOR IN DE TITEL
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
% Vul de naam van de opdracht in.
|
||||||
|
\assignment{The Return of the MyHyvesBook+}
|
||||||
|
% Vul het soort opdracht in.
|
||||||
|
\assignmenttype{Projectplan}
|
||||||
|
% Vul de titel van de eindopdracht in.
|
||||||
|
\title{MyHyvesBookPlusTagram Wordt H\'et Nieuwe Multimedia Platform}
|
||||||
|
|
||||||
|
% 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
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% INHOUDSOPGAVE
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% ACHTERGROND
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\section{Achtergrond}
|
||||||
|
Wij zijn benaderd door MyHyvesBook+; een softwaregigant binnen de social media. Zij willen hun doelgroep van jongeren beter bereiken door aan de naam \textit{MyHyvesBook+} naast de reeds succesvolle website, ook een android app toe te voegen. De implementatievoorwaarden zijn eenvoudig: er moet duidelijk sprake zijn van multimedia-integratie doormiddel van foto's en/of geluid.
|
||||||
|
Wij hebben inspiratie gehaald uit een minder multimedia platform dat reeds bestaat en willen dit naar onze eigen hand implementeren om een extra dimensie toe te voegen aan MyHyvesBook+. De app zal dan ook heten: \textit{MyHyvesBookPlusTagram}.
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% DOELEN
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\section{Projectdoelstelling}
|
||||||
|
Onze doelstelling is het verzorgen van een prettige, nieuwe ervaring voor de leden van MyHyvesBook+. De doelgroep van jongeren is van groot belang voor de success van dit project, omdat vrijwel alle jongeren een smartphone bezitten. Momenteel heeft MyHyvesBook+ nog onvoldoende mogelijkheden voor de smartphonegebruiker toegevoegd. Dat zal moeten veranderen met deze app. Modernisering is het sleutelwoord bij dit project.
|
||||||
|
|
||||||
|
\subsection{Doelstellling}
|
||||||
|
Het doel is gehoor te geven aan de vraag van de gebruiker en \textit{H\'et Nieuwe Multimedia Platform} op te stellen. Dit zal gedaan worden in de vorm van een gratis te verkrijgen android applicatie die gebruik maakt van foto's om een publiekelijke feed te cre\"eeren; transparant maar veilig. Conform de kernide\"een die MyHyvesBook+ hanteert en garandeerd.
|
||||||
|
|
||||||
|
\subsection{Visie}
|
||||||
|
Onze visie is het simpel en snel weergeven van afbeeldingen waarop de welbekende "niet-slecht"\space kan worden gegeven. Uiteraard ondersteunt de app het direct uploaden van en filters toevoegen aan foto's.
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% RESULTAAT
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\section{Projectresultaat}
|
||||||
|
De kenmerken van de app zijn eenvoud en snelheid. Dit zal worden bereikt door zoveel mogelijk modulariteit te gebruiken. Zo zal de backend worden verzorgd door \textit{Firebase}; een mobiel -en webapplicatie ontwikkelingsplatform wat de ontwikkeling van professionele apps vereenvoudigd en versnelt. Hier is voor gekozen om cross-platform compatibiliteit voor nu en de toekomst te bevorderen en om de snelheidswinst die ermee kan worden behaald, gezien de strakke planning en de naderende deadline. De verwachte \textit{releasedate} van de app is 27 juni 2017.
|
||||||
|
Naast Firebase zal gebruik worden gemaakt van de diverse reeds beschikbare API's om maximale prestaties en eenvoud te garanderen. Denk hierbij aan API's voor het opslaan van afbeeldingen in een online database, het toepassen van filters op afbeeldingen etc.
|
||||||
|
\linebreak
|
||||||
|
\\
|
||||||
|
Alvorens deze beslissingen zijn gemaakt, is overleg geweest met zowel het bestuur bij MyHyvesBook+ als onderling binnen onze groep.
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% ORGANISATIE
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\section{Projectorganisatie}
|
||||||
|
Hieronder staat de rolverdeling waaraan wij ons gaan houden. Deze rolverdeling is opgesteld aan de hand van het 4W-model: Wie, wat, Waarom, Wanneer.
|
||||||
|
|
||||||
|
\subsection{Rollen}
|
||||||
|
\textbf{Projectmanager en gitmaster}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wie: Marijn
|
||||||
|
\item Wat: Het leiden van het team naar succes. Belangrijk is hierbij dat de beslissingen over onderdelen van de app samen met de eindverantwoordelijke van dat onderdeel worden genomen. Mocht dit leiden tot een impasse, kan de voorzitter worden ingeschakelt om te stemmen. Ook zal Marijn zorgen dat de git repo overzichtelijk blijft en wordt hij het aanspreekpunt bij problemen.
|
||||||
|
\item Waarom: Om te zorgen voor een goede samenwerking en sfeer, productiviteit bevordering en een stabiele version-control.
|
||||||
|
\item Wanneer: Tijdens het gehele project, wanneer niet aanwezig op de UvA vrijwel altijd beschikbaar via telefoon.
|
||||||
|
\end{itemize}
|
||||||
|
\textbf{Notulist en Voorzitter}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wie: Niels
|
||||||
|
\item Wat: Vaart houden in de vergaderingen en nauw samenwerken met de projectmanager om te zorgen dat beslissingen worden genomen binnen tijdsbestek. Daarnaast worden notules gemaakt van de vergaderingen.
|
||||||
|
\item Waarom: Zodat de vergaderingen soepel en snel verlopen en belangrijke beslissingen niet te lang op zich laten wachten. Ook kunnen de notules worden gebruikt tijdens de individuele verslagen.
|
||||||
|
\item Wanneer: Tijdens vergaderingen en vlak erna voor het afronden van de notulen.
|
||||||
|
\end{itemize}
|
||||||
|
\textbf{Design}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wie: Felix
|
||||||
|
\item Wat: De eindbeslissingen nemen met betrekking tot design van zowel de poster als de app. Kan taken delegeren onder de overige leden maar houdt het nauwgezet in de gaten. Wordt gezien als de all-round werker die ook taken op zich kan nemen anders dan design. Essentieel dat er goed overleg plaatsvindt zodat de wensen van zowel de groep als opdrachtgever in acht worden genomen.
|
||||||
|
\item Waarom: Zodat het eindplaatje presenteerbaar is.
|
||||||
|
\item Wanneer: Gedurende het gehele project.
|
||||||
|
\end{itemize}
|
||||||
|
\textbf{Backend}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wie: Paul
|
||||||
|
\item Wat: Het bijhouden en consistent houden van alle code die wordt geschreven zoals algoritmes, database bijhouden en de uiteindelijke beslissingen nemen over Firebase. Tijdens vergaderingen telt Paul's stem strenger over beslissingen met betrekking tot deze punten dan die van anderen.
|
||||||
|
\item Waarom: Dit moet gebeuren om inconsistenties en niet-modulariteit tegen te gaan. Daarnaast moet de code duidelijk en begrijpelijk blijven om maximale productiviteit te stimuleren.
|
||||||
|
\item Wanneer: Continue tijdens het project; blijvend proces.
|
||||||
|
\end{itemize}
|
||||||
|
\pagebreak
|
||||||
|
\subsection{Communicatie}
|
||||||
|
Het team vergadert in principe twee keer per week; eenmaal op de maandag en eenmaal op de vrijdag. Dit resulteert in drie vergaderingen. Deze vergaderingen zullen zijn van 11:00 tot 12:00 onder voorbehoud dat iedereen aanwezig kan zijn (dan wel fysiek, dan wel over Skype/andere dienst).
|
||||||
|
Mocht een vergadering verplaatst worden, dan wordt dit tijdig aangegeven: minimaal 24 uur van tevoren tenzij er een geldige reden wordt opgegeven.
|
||||||
|
Afmelden voor vergaderingen wordt gedaan bij de voorzitter met opgave van de (globale) reden tot verzuim. Wederom 24 uur van tevoren, tenzij dit niet mogelijk is.\\\\
|
||||||
|
\noindent
|
||||||
|
Naast de vergaderingen zal er gebruik worden gemaakt van media zoals Telegram en Skype om te communiceren. Voor version-control zal git worden gebruikt en bijgehouden door de git-master. Ook wordt gebruik gemaakt van Trello; een online planner die voor iedereen een duidelijk overzicht geeft van "To do", "Busy"\space en "Done"\space taken.
|
||||||
|
|
||||||
|
\subsection{Verantwoording van geleverd werk}
|
||||||
|
De individuele bijdragen worden bepaald doordat de voorzitter tijdens de vergaderingen bijhoudt of alles volgens schema verloopt. Tijdens de eerste offici\"ele vergadering van het project op 19 juni 2017 zal een kort schema opgesteld worden met interne deadlines per onderdeel per persoon. Deze deadlines zijn geen harde deadlines maar meer een streefpunt. Zolang hier niet te ver van wordt afgeweken, zal het project in goede banen verlopen. De voorzitter houdt de progressie bij van alle leden en zij zullen dan ook melden als zij een bepaald onderdeel lang niet af gaan redden. Mocht dit het geval zijn, legt de voorzitter dit probleem voor bij de projectleider. Deze kan dan besluiten een spoedvergadering op te zetten bij een lastig probleem of kan besluiten het probleem direct op te lossen bij kleinere problemen.
|
||||||
|
Dit schema inclusief de (zachte) deadlines zal worden gepubliceerd op Trello
|
||||||
|
voor maximale transparantie en overzicht. Hierdoor kunnen leden dan ook bij het voltooien van een taak, eenvoudig aangeven dat deze taak voltooid is.
|
||||||
|
|
||||||
|
\subsection{Werkafspaken}
|
||||||
|
Bovenstaande subsecties bevatten al een en ander van de werkafspraken, maar hieronder volgt nog een uiteindelijke samenvatting:
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Verantwoordelijkheid ligt bij elk lid van de groep per onderdeel apart.
|
||||||
|
Bij problemen is het ook die persoon zijn verantwoordelijkheid hier op tijd melding van te maken.
|
||||||
|
\item Vergaderingen hebben een vaste starttijd en daar dient zo min mogelijk van afgeweken te worden. Ieder lid wordt geacht aanwezig te zijn en bij te dragen aan het gesprek in enkele zin.
|
||||||
|
\item De verschillende eindverantwoordelijken maken belangrijke beslissingen in principe alleen in overleg met de projectleider, tenzij hier een impasse ontstaat. In dat geval zal er worden gestemd met een zwaarder wegende stem voor de eindverantwoordelijke.
|
||||||
|
\item Transparantie en openheid staan centraal bij onze groep. Dit betekent dat er tijdig wordt aangegeven als iets niet goed gaat (met de opdracht of tussen groepsleden) en deze feedback wordt serieus in overweging genomen. Er is onvoldoende tijd om rechtertje te spelen, dus er wordt maximale inzet en medewerking verwacht van alle leden.
|
||||||
|
\item Tijdens vergaderingen zullen notules worden gemaakt en op gitlab worden gepubliceerd zodat deze gemakkelijk terug te vinden zijn. Hierin staan de besproken onderwerpen en beslissingen, en de positieve en negatieve punten die naar voren zijn gekomen.
|
||||||
|
\item Zachte deadlines worden zoveel mogelijk nageleefd en anders snel ingehaald. Tijd is niet aan onze kant en dus zal er hard gewerkt moeten worden om van MyHyvesBookPlusTagram het grote succes te maken dat het zeker verdient te zijn!
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% PLANNING
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
%Zet de planning indien gewenst in een apart document
|
||||||
|
\section{Planning}
|
||||||
|
|
||||||
|
Wij hebben de planning gemaakt volgens een simpel schema, omdat het implementeren van een strokenplan ons inziens niet nuttig was voor een kort tijdsbestek als het onze. Onderstaand schema laat zien wat de geplande activiteiten zijn van datum tot datum per persoon. Ook hebben wij harde deadlines die ons zijn opgelegd door de opdrachtgever in de planning verwerkt.
|
||||||
|
|
||||||
|
\subsection{Schema}
|
||||||
|
\textbf{19-6-2017 - 23-6-2017}\\
|
||||||
|
Eerste offici\"ele dag project.\\
|
||||||
|
Eerste vergadering van 11:00 - 12:00.\\\\
|
||||||
|
Marijn: \space\space Login/register systeem opzetten.\\
|
||||||
|
Felix: \space\space\space\space Camera-view implementeren.\\
|
||||||
|
Paul: \space\space\space\space Profielpagina implementeren.\\
|
||||||
|
Niels: \space\space\space\space Notulen van vergadering bijwerken + Paul ondersteunen.\\
|
||||||
|
\\
|
||||||
|
\noindent
|
||||||
|
\textbf{23-6-2017 - 26-6-2017}\\
|
||||||
|
Tweede vergadering van 11:00 - 12:00\\\\
|
||||||
|
Marijn: \space\space Uploaden van afbeeldingen werkend maken\\
|
||||||
|
Felix: \space\space\space\space Filters toevoegen, andere groepsleden ondersteunen waar mogelijk en nodig.\\
|
||||||
|
Paul: \space\space\space\space Teksten schrijven voor poster en flyer, algoritmes goed uitleggen in deze onderdelen. Ondersteuning door Niels.\\
|
||||||
|
Niels: \space\space\space\space Notulen van vergadering bijwerken, andere groepsleden ondersteunen waar mogelijk en nodig.\\
|
||||||
|
\\
|
||||||
|
\noindent
|
||||||
|
\textbf{26-6-2017}\\
|
||||||
|
Gezamelijk bugtesten, proberen de app te breken. Afhankelijk van de voortgang de afgelopen week kan er worden ingesprongen om onderdelen af te maken die we af wilden hebben. Database wordt gevuld met entries zodat we iets ter weergave kunnen aanbieden tijdens de posterpresentatie.
|
||||||
|
\\\\
|
||||||
|
\noindent
|
||||||
|
\textbf{28-6-2017}\\
|
||||||
|
Individueel verslag inleveren. Laatste tests van onze code.
|
||||||
|
\\\\
|
||||||
|
\noindent
|
||||||
|
\textbf{29-6-2017}\\
|
||||||
|
Poster inleveren en afronden van enige en alle code + commentaar. Code inleveren voor 0:00.
|
||||||
|
\\\\
|
||||||
|
\noindent
|
||||||
|
\textbf{30-6-2017}\\
|
||||||
|
Posterpresentatie.
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% BIJLAGEN EN EINDE
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%\section{Bijlage A}
|
||||||
|
%\section{Bijlage B}
|
||||||
|
%\section{Bijlage C}
|
||||||
|
|
||||||
|
\end{document}
|
||||||