com.shalzz.attendance.controllers.AttendanceController.java Source code

Java tutorial

Introduction

Here is the source code for com.shalzz.attendance.controllers.AttendanceController.java

Source

/*
 * Copyright (c) 2013-2016 Shaleen Jain <shaleen.jain95@gmail.com>
 *
 * This file is part of UPES Academics.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.shalzz.attendance.controllers;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;

import com.clockbyte.admobadapter.expressads.AdmobExpressRecyclerAdapterWrapper;
import com.google.android.gms.ads.AdSize;
import com.malinskiy.materialicons.IconDrawable;
import com.malinskiy.materialicons.Iconify;
import com.shalzz.attendance.DatabaseHandler;
import com.shalzz.attendance.Miscellaneous;
import com.shalzz.attendance.R;
import com.shalzz.attendance.activity.MainActivity;
import com.shalzz.attendance.adapter.ExpandableListAdapter;
import com.shalzz.attendance.fragment.AttendanceListFragment;
import com.shalzz.attendance.loader.SubjectAsyncTaskLoader;
import com.shalzz.attendance.model.remote.Subject;
import com.shalzz.attendance.network.DataAPI;
import com.shalzz.attendance.network.RetrofitException;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import timber.log.Timber;

public class AttendanceController implements LoaderManager.LoaderCallbacks<List<Subject>> {

    public static final String SUBJECT_FILTER = "subject_filter_text";

    private AttendanceListFragment mView;
    private ExpandableListAdapter mAdapter;
    private DatabaseHandler db;
    private Context mContext;
    private Resources mResources;
    private View mFooter;
    private final DataAPI api;
    private final AdmobExpressRecyclerAdapterWrapper adapterWrapper;

    @Inject
    public AttendanceController(Context context, AttendanceListFragment view, DataAPI api) {
        mContext = context;
        mResources = context.getResources();
        mView = view;
        db = new DatabaseHandler(mContext);
        this.api = api;

        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext);
        int expandLimit = Integer
                .parseInt(sharedPref.getString(mContext.getString(R.string.pref_key_sub_limit), "3"));

        mAdapter = new ExpandableListAdapter(mContext, mView);
        mAdapter.setLimit(expandLimit);
        LayoutInflater inflater = mView.getActivity().getLayoutInflater();
        mFooter = inflater.inflate(R.layout.list_footer, mView.mRecyclerView, false);
        mFooter.setVisibility(View.INVISIBLE);
        mAdapter.addFooter(mFooter);

        String unit_id;
        int currentNightMode = mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;

        if (currentNightMode == Configuration.UI_MODE_NIGHT_YES)
            unit_id = mContext.getString(R.string.native_black_attendance_ad);
        else
            unit_id = mContext.getString(R.string.native_white_attendance_ad);

        adapterWrapper = new AdmobExpressRecyclerAdapterWrapper(mContext, unit_id,
                new AdSize(AdSize.FULL_WIDTH, 100));

        adapterWrapper.setAdapter(mAdapter);

        adapterWrapper.setLimitOfAds(1);
        adapterWrapper.setNoOfDataBetweenAds(5);
        adapterWrapper.setFirstAdIndex(5);

        mView.mRecyclerView.setAdapter(adapterWrapper);
    }

    public void destroyAds() {
        adapterWrapper.destroyAds();
    }

    public void updateSubjects() {
        Call<List<Subject>> call = api.getAttendance();
        call.enqueue(new Callback<List<Subject>>() {
            @Override
            public void onResponse(Call<List<Subject>> call, Response<List<Subject>> response) {
                done();
                toggleEmptyViewVisibility(false);

                List<Subject> subjects = response.body();

                long now = new Date().getTime();
                for (Subject subject : subjects) {
                    db.addSubject(subject, now);
                }

                if (db.purgeOldSubjects() == 1) {
                    Timber.i("Purging Subjects...");
                    mAdapter.clear();
                }

                db.close();

                // Don't update the view, if there isn't one.
                if (mView == null)
                    return;
                mAdapter.addAll(subjects);
                mView.showcaseView();
                // Update the drawer header
                MainActivity activity = (MainActivity) mView.getActivity();
                if (activity != null)
                    activity.updateLastSync();
            }

            @Override
            public void onFailure(Call<List<Subject>> call, Throwable t) {
                if (mView == null || mView.getActivity() == null)
                    return;

                RetrofitException error = (RetrofitException) t;
                if (db.getSubjectCount() > 0 && (error.getKind() == RetrofitException.Kind.NETWORK
                        || error.getKind() == RetrofitException.Kind.EMPTY_RESPONSE)) {
                    View view = mView.getActivity().findViewById(android.R.id.content);
                    Snackbar.make(view, error.getMessage(), Snackbar.LENGTH_LONG)
                            .setAction("Retry", v -> updateSubjects()).show();
                } else if (error.getKind() == RetrofitException.Kind.NETWORK) {
                    Drawable emptyDrawable = new IconDrawable(mView.getContext(), Iconify.IconValue.zmdi_wifi_off)
                            .colorRes(android.R.color.darker_gray);
                    mView.mEmptyView.ImageView.setImageDrawable(emptyDrawable);
                    mView.mEmptyView.TitleTextView.setText(R.string.no_connection_title);
                    mView.mEmptyView.ContentTextView.setText(R.string.no_connection_content);
                    mView.mEmptyView.Button.setOnClickListener(v -> updateSubjects());
                    mView.mEmptyView.Button.setVisibility(View.VISIBLE);

                    toggleEmptyViewVisibility(true);
                } else if (error.getKind() == RetrofitException.Kind.EMPTY_RESPONSE) {
                    Drawable emptyDrawable = new IconDrawable(mView.getContext(), Iconify.IconValue.zmdi_cloud_off)
                            .colorRes(android.R.color.darker_gray);
                    mView.mEmptyView.ImageView.setImageDrawable(emptyDrawable);
                    mView.mEmptyView.TitleTextView.setText(R.string.no_data_title);
                    mView.mEmptyView.ContentTextView.setText(R.string.no_data_content);
                    mView.mEmptyView.Button.setVisibility(View.GONE);

                    toggleEmptyViewVisibility(true);

                    // Update the drawer header
                    ((MainActivity) mView.getActivity()).updateLastSync();
                } else if (error.getKind() == RetrofitException.Kind.HTTP) {
                    showError(error.getMessage());
                } else {
                    String msg = mResources.getString(R.string.unexpected_error);
                    showError(msg);
                    Timber.e(t, msg);
                }
                done();
            }
        });
    }

    private void toggleEmptyViewVisibility(boolean show) {
        if (mView == null || mView.mRecyclerView == null || mView.mEmptyView == null)
            return;
        if (show) {
            mView.emptyView.setVisibility(View.VISIBLE);
            mView.mRecyclerView.setVisibility(View.GONE);
        } else {
            mView.emptyView.setVisibility(View.GONE);
            mView.mRecyclerView.setVisibility(View.VISIBLE);
        }
    }

    private void showError(String message) {
        if (mView == null || mView.getActivity() == null)
            return;
        View view = mView.getActivity().findViewById(android.R.id.content);
        if (view != null)
            Miscellaneous.showSnackBar(view, message);
    }

    public void done() {
        if (mView.mProgress != null) {
            mView.mProgress.setVisibility(View.GONE);
        }
        if (mView.mSwipeRefreshLayout != null) {
            mView.mSwipeRefreshLayout.setRefreshing(false);
        }
    }

    @Override
    public Loader<List<Subject>> onCreateLoader(int id, Bundle args) {
        String filter = null;
        if (args != null)
            filter = args.getString(SUBJECT_FILTER);
        return new SubjectAsyncTaskLoader(mContext, filter);
    }

    @Override
    public void onLoadFinished(Loader<List<Subject>> loader, List<Subject> data) {
        String filter = ((SubjectAsyncTaskLoader) loader).mCurFilter;
        if (data.size() == 0 && filter == null) {
            updateSubjects();
        } else {
            done();
            mAdapter.addAll(data);
        }
    }

    @Override
    public void onLoaderReset(Loader<List<Subject>> loader) {
        // Loader reset, throw away our data,
        // unregister any listeners, etc.
        mAdapter.clear();
        // Of course, unless you use destroyLoader(),
        // this is called when everything is already dying
        // so a completely empty onLoaderReset() is
        // totally acceptable
    }
}