basbeu/theSofties

View on GitHub
app/src/main/java/ch/epfl/sweng/favors/main/LoggedInScreen.java

Summary

Maintainability
A
0 mins
Test Coverage
package ch.epfl.sweng.favors.main;

import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.databinding.Observable;
import android.databinding.ObservableField;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.Timestamp;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import ch.epfl.sweng.favors.R;
import ch.epfl.sweng.favors.authentication.Authentication;
import ch.epfl.sweng.favors.chat.ChatsList;
import ch.epfl.sweng.favors.database.Database;
import ch.epfl.sweng.favors.database.Favor;
import ch.epfl.sweng.favors.database.FavorRequest;
import ch.epfl.sweng.favors.database.ObservableArrayList;
import ch.epfl.sweng.favors.database.User;
import ch.epfl.sweng.favors.database.fields.DatabaseField;
import ch.epfl.sweng.favors.database.internal_db.LocalPreferences;
import ch.epfl.sweng.favors.database.storage.FirebaseStorageDispatcher;
import ch.epfl.sweng.favors.database.storage.StorageCategories;
import ch.epfl.sweng.favors.databinding.ActivityLoggedInScreenBinding;
import ch.epfl.sweng.favors.databinding.NavHeaderBinding;
import ch.epfl.sweng.favors.favors.MyFavorsFragment;
import ch.epfl.sweng.favors.notifications.NotificationsFragment;
import ch.epfl.sweng.favors.location.LocationHandler;
import ch.epfl.sweng.favors.profile.ProfileFragment;
import ch.epfl.sweng.favors.settings.SettingsFragment;
import ch.epfl.sweng.favors.utils.ExecutionMode;
import ch.epfl.sweng.favors.utils.Utils;

public class LoggedInScreen extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

    public ObservableField<String> firstName = User.getMain().getObservableObject(User.StringFields.firstName);
    public ObservableField<String> lastName = User.getMain().getObservableObject(User.StringFields.lastName);
    public ObservableField<String> location = LocationHandler.getHandler().locationCity;
    public final String TAG = "LOGGED_IN_SCREEN";
    private Uri selectedImage = ExecutionMode.getInstance().isTest() ? Uri.parse("test/picture") : null;
    private String storageRef;
    private ObservableField<String> profilePictureRef;
    private FirebaseStorageDispatcher storage = FirebaseStorageDispatcher.getInstance();
    private OnSuccessListener deleteSuccess = new OnSuccessListener() {
        @Override
        public void onSuccess(Object o) {
            User.getMain().set(User.StringFields.profilePicRef, null);
            headerBinding.profilePicture.setImageDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
        }
    };

    ActivityLoggedInScreenBinding binding;
    NavHeaderBinding headerBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        User.getMain().reset();
        User.getMain().addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if(propertyId == User.UpdateType.FROM_DB.ordinal()){
                    // Must be remove when fake requests with multiple queries will be implemented
                    reimburseExpiredFavors();
                    sender.removeOnPropertyChangedCallback(this);
                }
            }
        });
        Database.getInstance().updateFromDb(User.getMain());

        binding = DataBindingUtil.setContentView(this, R.layout.activity_logged_in__screen);
        binding.setElements(this);

        binding.navView.setNavigationItemSelectedListener(this);
        headerBinding = DataBindingUtil.inflate(getLayoutInflater(),
                R.layout.nav_header, binding.navView, false);
        headerBinding.setElements(this);

        headerBinding.topView.setBackgroundResource(LocalPreferences.getInstance().getColor());
        binding.navView.addHeaderView(headerBinding.getRoot());

        profilePictureRef = User.getMain().getObservableObject(User.StringFields.profilePicRef);
        Database.getInstance().updateFromDb(User.getMain()).addOnSuccessListener(v -> storage.displayImage(profilePictureRef, headerBinding.profilePicture, StorageCategories.PROFILE));

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, binding.drawerLayout,
                binding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);

        binding.drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        if(savedInstanceState == null){
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new Home()).commit();
            binding.navView.setCheckedItem(R.id.favors);
        }

        binding.toolbar.setBackgroundResource(LocalPreferences.getInstance().getColor());

        headerBinding.uploadProfilePicture.setOnClickListener(v-> startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), FirebaseStorageDispatcher.GET_FROM_GALLERY));
        headerBinding.deleteProfilePicture.setOnClickListener(v -> Database.getInstance().updateFromDb(User.getMain()).addOnSuccessListener(t -> storage.deleteImageFromStorage(profilePictureRef, StorageCategories.PROFILE).addOnSuccessListener(deleteSuccess)));
    }

    @Override
    public void onBackPressed() {
        if(binding.drawerLayout.isDrawerOpen(GravityCompat.START)){
            binding.drawerLayout.closeDrawer(GravityCompat.START);
        }
        else{
            super.onBackPressed();
        }
    }

    /**
     * This method is called on the result of method startActivityOnResult
     * Inspired from this tutorial : https://code.tutsplus.com/tutorials/image-upload-to-firebase-in-android-application--cms-29934
     * @param requestCode 66 if the activity is getting a picture from the gallery
     * @param resultCode -1 if OK
     * @param data the data corresponding to the picture
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bitmap = null;
        if(resultCode == -1) {
            bitmap = FirebaseStorageDispatcher.getInstance().getPictureFromDevice(requestCode, data, this, headerBinding.profilePicture);
        }
        if(bitmap != null) {
            selectedImage = data.getData();
            storageRef = storage.uploadImage(FirebaseStorageDispatcher.getInstance().getReference(), this, selectedImage, StorageCategories.PROFILE);
            ObservableField<String> oldRef = User.getMain().getObservableObject(User.StringFields.profilePicRef);
            storage.deleteImageFromStorage(oldRef, StorageCategories.PROFILE);
            User.getMain().set(User.StringFields.profilePicRef, storageRef);
            Database.getInstance().updateOnDb(User.getMain());
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId())
        {
            case R.id.profile:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).addToBackStack(null).commit();
                break;
            case R.id.favors:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new Home()).addToBackStack(null).commit();
                break;
            case R.id.myfavors:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyFavorsFragment()).addToBackStack(null).commit();
                break;
            case R.id.settings:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).addToBackStack(null).commit();
                break;
            case R.id.notifications:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).addToBackStack(null).commit();
                break;
            case R.id.discussions:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ChatsList()).addToBackStack(null).commit();
                break;
            case R.id.logout:
                Utils.logout(this, Authentication.getInstance());
                Toast.makeText(this, R.string.seeyou, Toast.LENGTH_SHORT).show();
                break;

        }

        binding.drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

    public void logout(){
        User.getMain().set(User.StringFields.token_id, "");
        Context context = this;
        Database.getInstance().updateOnDb(User.getMain()).addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean aVoid) {
                Utils.logout(context, Authentication.getInstance());
            }
        }).addOnFailureListener(e -> Log.e("LOGOUT", "Error logging out!"));
    }

    void reimburseExpiredFavors(){
        ObservableArrayList<Favor> listFavors = new ObservableArrayList<>();
        Map<DatabaseField, Object> querryLess = new HashMap<>();
        Map<DatabaseField, Object> querryEqual = new HashMap<>();
        Map<DatabaseField, Object> querryGreater = new HashMap<>();


        querryEqual.put(Favor.StringFields.ownerID, Authentication.getInstance().getUid());
        querryLess.put(Favor.ObjectFields.expirationTimestamp,new Timestamp(new Date()));
        querryGreater.put(Favor.LongFields.nbPerson,0);

        FavorRequest.getList(listFavors,querryEqual,querryLess,null,null,null);

        listFavors.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if(propertyId != ObservableArrayList.ContentChangeType.Update.ordinal()){
                    return;
                }
                long toReimburseTotal = 0;
                Log.d(TAG, "We have received " + listFavors.size());
                for (Favor f : listFavors) {
                    Log.d(TAG, "The value are: " + f.get(Favor.StringFields.title));
                    if(f.get(Favor.ObjectFields.interested) == null || ((ArrayList<String>)f.get(Favor.ObjectFields.interested)).isEmpty()){
                        Log.d(TAG, "This favor is being treated: "+f.get(Favor.StringFields.title));
                        long nbPersonneRemaining = f.get(Favor.LongFields.nbPerson);
                        long tokenPerPerson = f.get(Favor.LongFields.tokenPerPerson);
                        f.set(Favor.LongFields.nbPerson,0L);
                        //f.set(Favor.LongFields.tokenPerPerson,0L);
                        toReimburseTotal += nbPersonneRemaining * tokenPerPerson;
                        Database.getInstance().updateOnDb(f);
                    }
                    else{Log.d(TAG, "This favor is being not being treated: "+f.get(Favor.StringFields.title));}
                }
                long currentUserTokense = User.getMain().get(User.LongFields.tokens);
                currentUserTokense += toReimburseTotal;
                User.getMain().set(User.LongFields.tokens,currentUserTokense);
                Database.getInstance().updateOnDb(User.getMain());
            }
        });
    }
}