org.jorge.cmp.ui.activity.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.jorge.cmp.ui.activity.MainActivity.java

Source

/*
 * This file is part of LoLin1.
 *
 * LoLin1 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.
 *
 * LoLin1 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 LoLin1. If not, see <http://www.gnu.org/licenses/>.
 *
 * Created by Jorge Antonio Diaz-Benito Soriano.
 */

package org.jorge.cmp.ui.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.sothree.slidinguppanel.SlidingUpPanelLayout;

import org.jorge.cmp.LoLin1Application;
import org.jorge.cmp.R;
import org.jorge.cmp.auth.LoLin1AccountAuthenticator;
import org.jorge.cmp.chat.FriendManager;
import org.jorge.cmp.datamodel.FeedArticle;
import org.jorge.cmp.datamodel.LoLin1Account;
import org.jorge.cmp.datamodel.Realm;
import org.jorge.cmp.io.database.SQLiteDAO;
import org.jorge.cmp.io.prefs.PreferenceAssistant;
import org.jorge.cmp.service.ChatIntentService;
import org.jorge.cmp.ui.adapter.ChatAdapter;
import org.jorge.cmp.ui.adapter.NavigationDrawerAdapter;
import org.jorge.cmp.ui.fragment.ArticleReaderFragment;
import org.jorge.cmp.ui.fragment.CommunityListFragment;
import org.jorge.cmp.ui.fragment.NavigationDrawerFragment;
import org.jorge.cmp.ui.fragment.NewsListFragment;
import org.jorge.cmp.ui.fragment.SchoolListFragment;
import org.jorge.cmp.util.Interface;
import org.jorge.cmp.util.PicassoUtils;
import org.jorge.cmp.util.Utils;

import java.util.Arrays;
import java.util.Stack;
import java.util.concurrent.Executors;

public class MainActivity extends ActionBarActivity
        implements Interface.IOnFeedArticleClickedListener, NavigationDrawerAdapter.NavigationDrawerCallbacks {

    public static final String KEY_LOLIN1_ACCOUNT = "KEY_LOLIN1_ACCOUNT";
    public static final String KEY_OPEN_CHAT = "KEY_OPEN_CHAT";
    private Context mContext;
    private Fragment[] mContentFragments;
    private NavigationDrawerFragment mNavigationDrawerFragment;
    private Stack<Integer> mNavigatedIndexesStack;
    private LoLin1Account mAccount;
    private BroadcastReceiver mChatBroadcastReceiver;
    private Boolean mAlreadyInited = Boolean.FALSE;
    private View mLoginProgress;
    private ImageView mLoginStatus;
    private ChatAdapter mChatAdapter;
    private TextView mEmptyView;
    private String mTag = getClass().getName();
    private SlidingUpPanelLayout mSlidingLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mNavigatedIndexesStack = new Stack<>();
        mNavigatedIndexesStack.push(0);
        setContentView(R.layout.activity_main);

        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setHomeButtonEnabled(Boolean.TRUE);

        mContext = LoLin1Application.getInstance().getContext();

        mAccount = getIntent().getParcelableExtra(KEY_LOLIN1_ACCOUNT);
        final Boolean comesFromNotification;
        if (comesFromNotification = mAccount == null)
            mAccount = LoLin1AccountAuthenticator.loadAccount(mContext);

        mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
                .findFragmentById(R.id.navigation_drawer_fragment);
        setupNavigationDrawer(toolbar, mAccount);

        mSlidingLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
        mLoginProgress = findViewById(R.id.progress_bar);
        mLoginStatus = (ImageView) findViewById(R.id.login_status_image);
        final TextView chatActionView = (TextView) findViewById(R.id.chat_view_action);
        mSlidingLayout.setDragView(chatActionView);
        mSlidingLayout.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
            @Override
            public void onPanelSlide(View view, float v) {
                //Unused
            }

            @Override
            public void onPanelCollapsed(View view) {
                MainActivity.this.mNavigationDrawerFragment.unlockDrawer();
                chatActionView.setText(R.string.chat_view_action_expand);
            }

            @Override
            public void onPanelExpanded(View view) {
                MainActivity.this.mNavigationDrawerFragment.lockDrawerClosed();
                chatActionView.setText(R.string.chat_view_action_collapse);
            }

            @Override
            public void onPanelAnchored(View view) {
                MainActivity.this.mNavigationDrawerFragment.lockDrawerClosed();
                chatActionView.setText(R.string.chat_view_action_collapse);
            }

            @Override
            public void onPanelHidden(View view) {
                MainActivity.this.mNavigationDrawerFragment.unlockDrawer();
                chatActionView.setText(R.string.chat_view_action_expand);
            }
        });

        setupChatView();
        if (!comesFromNotification)
            initChat();
        else {
            mNavigationDrawerFragment.asyncLoadUserImage(mAccount);
            requestChatListRefresh();
            showChatViewConnected();
        }

        if (mContentFragments == null)
            showInitialFragment();
    }

    private void setupChatView() {
        final RecyclerView chatRecyclerView = (RecyclerView) findViewById(R.id.chat_recycler_view);
        chatRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        chatRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        mEmptyView = (TextView) findViewById(android.R.id.empty);
        mChatAdapter = new ChatAdapter(mContext, mEmptyView, mTag);
        chatRecyclerView.setHasFixedSize(Boolean.FALSE);
        chatRecyclerView.setAdapter(mChatAdapter);
        chatRecyclerView.setItemAnimator(new DefaultItemAnimator());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        PicassoUtils.cancel(mContext, mTag);
    }

    private void initChat() {
        final View thisView = findViewById(android.R.id.content);
        registerLocalBroadcastReceiver();
        if (mAlreadyInited) {
            if (!Utils.isInternetReachable()) {
                thisView.post(new Runnable() {
                    @Override
                    public void run() {
                        showChatViewNoConnection();
                    }
                });
            } else {
                if (!ChatIntentService.isLoggedIn()) {
                    thisView.post(new Runnable() {
                        @Override
                        public void run() {
                            showChatViewLoading();
                        }
                    });
                    runChat();
                } else {
                    thisView.post(new Runnable() {
                        @Override
                        public void run() {
                            showChatViewConnected();
                        }
                    });
                }
            }
            return;
        }
        final Runnable viewRunnable;
        if (!Utils.isInternetReachable()) {
            viewRunnable = new Runnable() {
                @Override
                public void run() {
                    showChatViewNoConnection();
                }
            };
        } else {
            viewRunnable = new Runnable() {
                @Override
                public void run() {
                    showChatViewLoading();
                }
            };
            if (!ChatIntentService.isLoggedIn()) {
                runChat();
            }
        }
        thisView.post(viewRunnable);

        if (getIntent().getBooleanExtra(KEY_OPEN_CHAT, Boolean.FALSE) && !mSlidingLayout.isPanelExpanded()) {
            mSlidingLayout.expandPanel();
        }
    }

    private void showChatViewLoading() {
        mLoginStatus.setVisibility(View.GONE);
        mLoginStatus.setContentDescription(getString(R.string.chat_status_loading_content_description));
        mLoginProgress.setVisibility(View.VISIBLE);
        mEmptyView.setText(getString(R.string.chat_friend_list_empty_loading));
    }

    private void showChatViewConnected() {
        mLoginProgress.setVisibility(View.GONE);
        mLoginStatus.setVisibility(View.VISIBLE);
        mLoginStatus.setContentDescription(getString(R.string.chat_status_logged_in_content_description));
        mLoginStatus.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_logged_in));
        mEmptyView.setOnClickListener(null);
        mEmptyView.setText(getString(R.string.chat_friend_list_empty_no_online_friends));
    }

    private void showChatViewNoConnection() {
        mLoginProgress.setVisibility(View.GONE);
        mLoginStatus.setVisibility(View.VISIBLE);
        mLoginStatus.setContentDescription(getString(R.string.chat_status_no_connection_content_description));
        mLoginStatus.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_error));
        mEmptyView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Utils.isInternetReachable() && !ChatIntentService.isLoggedIn()) {
                    showChatViewLoading();
                    MainActivity.this.runChat();
                }
            }
        });
        mEmptyView.setText(getString(R.string.chat_friend_list_empty_no_connection));
    }

    private void showChatViewWrongCredentials() {
        mLoginProgress.setVisibility(View.GONE);
        mLoginStatus.setVisibility(View.VISIBLE);
        mLoginStatus.setContentDescription(getString(R.string.chat_status_wrong_credentials_content_description));
        mLoginStatus.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_warning));
        mEmptyView.setOnClickListener(null);
        mEmptyView.setText(getString(R.string.chat_friend_list_empty_wrong_credentials));
    }

    private void showInitialFragment() {
        if (mContentFragments == null) {
            mContentFragments = new Fragment[4];
        }
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_fragment_container, findNewsListFragment()).commitAllowingStateLoss();
    }

    private Fragment findNewsListFragment() {
        if (mContentFragments[0] == null)
            mContentFragments[0] = NewsListFragment.newInstance(mContext,
                    Realm.getInstanceByRealmId(mAccount.getRealmEnum()));
        return mContentFragments[0];
    }

    private Fragment findCommunityListFragment() {
        if (mContentFragments[1] == null)
            mContentFragments[1] = CommunityListFragment.newInstance(mContext);
        return mContentFragments[1];
    }

    private Fragment findSchoolListFragment() {
        if (mContentFragments[2] == null)
            mContentFragments[2] = SchoolListFragment.newInstance(mContext);
        return mContentFragments[2];
    }

    private Fragment findChatFragment() {
        throw new UnsupportedOperationException("Not yet implemented.");
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        if (getResources().getConfiguration().orientation != newConfig.orientation) {
            mNavigationDrawerFragment.selectItem(mNavigatedIndexesStack.peek());
            mNavigatedIndexesStack.pop(); //Remove the element that was added because of the
            // call to selectItem
        }

        super.onConfigurationChanged(newConfig);
    }

    /**
     * Launches an article reader.
     *
     * @param article The article information.
     * @param c       The class of the article list, so that the errorResId can be deducted
     *                in the ArticleReaderFragment constructor.
     */
    private void launchArticleReader(FeedArticle article, Class c) {
        //Link-type post auto-parsing
        if (article.getPreviewText().contentEquals("null")) {
            article.requestBrowseToAction(mContext);
            article.markAsRead();
            final Class newsClass = NewsListFragment.class;
            final Class communityClass = CommunityListFragment.class;
            final Class schoolClass = SchoolListFragment.class;
            String tableName;
            final Realm r = Realm.getInstanceByRealmId(mAccount.getRealmEnum());
            if (c == newsClass) {
                String l = PreferenceAssistant.readSharedString(mContext, PreferenceAssistant.PREF_LANG, null);
                if (l == null || !Arrays.asList(r.getLocales()).contains(l)) {
                    l = r.getLocales()[0];
                    PreferenceAssistant.writeSharedString(mContext, PreferenceAssistant.PREF_LANG, l);
                }
                tableName = SQLiteDAO.getNewsTableName(r, l);
            } else if (c == communityClass) {
                tableName = SQLiteDAO.getCommunityTableName();
            } else if (c == schoolClass) {
                tableName = SQLiteDAO.getSchoolTableName();
            } else {
                throw new IllegalArgumentException(
                        "Feed list fragment class " + c.getCanonicalName() + " not recognized.");
            }
            new AsyncTask<Object, Void, Void>() {
                @Override
                protected Void doInBackground(Object... params) {
                    SQLiteDAO.getInstance().markArticleAsRead((FeedArticle) params[0], (String) params[1]);
                    return null;
                }
            }.executeOnExecutor(Executors.newSingleThreadExecutor(), article, tableName);
            return;
        }

        Intent intent = new Intent(mContext, ArticleReaderActivity.class);

        intent.putExtra(ArticleReaderFragment.KEY_ARTICLE, article);
        intent.putExtra(ArticleReaderActivity.READER_LIST_FRAGMENT_CLASS, c);
        intent.putExtra(ArticleReaderFragment.KEY_ACCOUNT, mAccount);

        startActivity(intent);
        overridePendingTransition(R.anim.move_in_from_bottom, R.anim.move_out_to_bottom);
    }

    @Override
    public void onFeedArticleClicked(FeedArticle item, Class c) {
        launchArticleReader(item, c);
    }

    @Override
    public void onBackPressed() {
        Boolean handled = Boolean.FALSE;
        if (mNavigationDrawerFragment.isDrawerOpen()) {
            mNavigationDrawerFragment.closeDrawer();
            handled = Boolean.TRUE;
        }
        if (!handled && mContentFragments != null && mContentFragments[mNavigatedIndexesStack.peek()] != null
                && mContentFragments[mNavigatedIndexesStack.peek()] instanceof Interface.IOnBackPressed) {
            handled = ((Interface.IOnBackPressed) mContentFragments[mNavigatedIndexesStack.peek()]).onBackPressed();
        }
        if (!handled) {
            super.onBackPressed();
            if (mNavigatedIndexesStack.size() > 1) {
                mNavigatedIndexesStack.pop();
                mNavigationDrawerFragment.selectItem(mNavigatedIndexesStack.peek());
                mNavigatedIndexesStack.pop(); //Remove the element that was added because of the
                // call to selectItem
            } else
                finish();
        }
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        if (mNavigationDrawerFragment == null || mNavigationDrawerFragment.getPosition() == position) {
            return;
        }
        Fragment target;
        mNavigatedIndexesStack.push(position);
        switch (position) {
        case 0:
            target = findNewsListFragment();
            break;
        case 1:
            target = findCommunityListFragment();
            break;
        case 2:
            target = findSchoolListFragment();
            break;
        case 3:
            target = findChatFragment();
            break;
        default:
            throw new IllegalArgumentException("Menu with id " + position + " not found.");
        }
        final Fragment targetAsFinal = target;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.content_fragment_container, targetAsFinal).addToBackStack(null)
                        .commitAllowingStateLoss();
            }
        });
    }

    public void setupNavigationDrawer(Toolbar toolbar, LoLin1Account acc) {
        mNavigationDrawerFragment.setup(R.id.navigation_drawer_fragment,
                (DrawerLayout) findViewById(R.id.navigation_drawer), toolbar, acc);
    }

    private void runChat() {
        Intent intent = new Intent(mContext, ChatIntentService.class);
        if (ChatIntentService.isLoggedIn()) {
            stopService(intent);
        }
        Intent chatConnectIntent = new Intent(mContext, ChatIntentService.class);
        chatConnectIntent.setAction(ChatIntentService.ACTION_CONNECT);
        chatConnectIntent.putExtra(ChatIntentService.EXTRA_KEY_LOLIN1_ACCOUNT, mAccount);
        startService(chatConnectIntent);
    }

    private void registerLocalBroadcastReceiver() {
        if (mChatBroadcastReceiver != null) {
            return;
        }
        mChatBroadcastReceiver = new ChatOverviewBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        intentFilter.addAction(mContext.getString(R.string.event_login_failed));
        intentFilter.addAction(mContext.getString(R.string.event_chat_overview));
        intentFilter.addAction(mContext.getString(R.string.event_login_successful));
        intentFilter.addAction(mContext.getString(R.string.event_message_received));
        LocalBroadcastManager.getInstance(mContext).registerReceiver(mChatBroadcastReceiver, intentFilter);
    }

    private void stopChatService() {
        Intent chatDisconnectIntent = new Intent(mContext, ChatIntentService.class);
        chatDisconnectIntent.setAction(ChatIntentService.ACTION_DISCONNECT);
        startService(chatDisconnectIntent);
        mAlreadyInited = Boolean.FALSE;
        stopService(new Intent(mContext, ChatIntentService.class));
    }

    private synchronized void requestChatListRefresh() {
        FriendManager.getInstance().updateOnlineFriends();
        mChatAdapter.notifyFriendSetChanged();
    }

    public class ChatOverviewBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, final Intent intent) {
            String action = intent.getAction();
            if (action.contentEquals(context.getString(R.string.event_chat_overview))) {
                MainActivity.this.requestChatListRefresh();
            } else {
                final View thisView = findViewById(android.R.id.content);
                if (action.contentEquals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                    if (!Utils.isInternetReachable()) {
                        thisView.post(new Runnable() {
                            @Override
                            public void run() {
                                MainActivity.this.requestChatListRefresh();
                                showChatViewNoConnection();
                            }
                        });
                        if (ChatIntentService.isLoggedIn()) {
                            stopChatService();
                        }
                    } else {
                        MainActivity.this.runChat();
                    }
                } else if (action.contentEquals(context.getString(R.string.event_login_failed))) {
                    thisView.post(new Runnable() {
                        @Override
                        public void run() {
                            showChatViewWrongCredentials();
                        }
                    });
                    if (ChatIntentService.isLoggedIn()) {
                        stopChatService();
                    }
                } else if (action.contentEquals(context.getString(R.string.event_login_successful))) {
                    MainActivity.this.mAlreadyInited = Boolean.TRUE;
                    thisView.post(new Runnable() {
                        @Override
                        public void run() {
                            mNavigationDrawerFragment.asyncLoadUserImage(mAccount);
                            requestChatListRefresh();
                            showChatViewConnected();
                        }
                    });
                }
            }

        }
    }
}