package com.gh4a.activities.home;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.gh4a.BasePagerActivity;
import com.gh4a.Gh4Application;
import com.gh4a.R;
import com.gh4a.activities.Github4AndroidActivity;
import com.gh4a.activities.SettingsActivity;
import com.gh4a.activities.UserActivity;
import com.gh4a.fragment.RepositoryListContainerFragment;
import com.gh4a.fragment.SettingsFragment;
import com.gh4a.loader.LoaderCallbacks;
import com.gh4a.loader.LoaderResult;
import com.gh4a.loader.UserLoader;
import com.gh4a.utils.ApiHelpers;
import com.gh4a.utils.AvatarHandler;
import com.gh4a.utils.IntentUtils;
import org.eclipse.egit.github.core.User;
public class HomeActivity extends BasePagerActivity implements
View.OnClickListener, RepositoryListContainerFragment.Callback {
private static final int REQUEST_SETTINGS = 10000;
private FragmentFactory mFactory;
private ImageView mAvatarView;
private TextView mUserExtraView;
private ImageView mDrawerSwitcher;
private String mUserLogin;
private User mUserInfo;
private int mSelectedFactoryId;
private boolean mDrawerInAccountMode;
private Menu mLeftDrawerMenu;
private static final String STATE_KEY_FACTORY_ITEM = "factoryItem";
private static final int OTHER_ACCOUNTS_GROUP_BASE_ID = 1000;
private static final SparseArray<String> START_PAGE_MAPPING = new SparseArray<>();
static {
START_PAGE_MAPPING.put(R.id.news_feed, "newsfeed");
START_PAGE_MAPPING.put(R.id.notifications, "notifications");
START_PAGE_MAPPING.put(R.id.my_repos, "repos");
START_PAGE_MAPPING.put(R.id.my_issues, "issues");
START_PAGE_MAPPING.put(R.id.my_prs, "prs");
START_PAGE_MAPPING.put(R.id.my_gists, "gists");
START_PAGE_MAPPING.put(R.id.pub_timeline, "timeline");
START_PAGE_MAPPING.put(R.id.trend, "trends");
START_PAGE_MAPPING.put(R.id.blog, "blog");
START_PAGE_MAPPING.put(R.id.bookmarks, "bookmarks");
START_PAGE_MAPPING.put(R.id.search, "search");
}
private final LoaderCallbacks<User> mUserCallback = new LoaderCallbacks<User>(this) {
@Override
protected Loader<LoaderResult<User>> onCreateLoader() {
return new UserLoader(HomeActivity.this, mUserLogin);
}
@Override
protected void onResultReady(User result) {
Gh4Application.get().setCurrentAccountInfo(result);
mUserInfo = result;
updateUserInfo();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
mUserLogin = Gh4Application.get().getAuthLogin();
if (savedInstanceState != null) {
mSelectedFactoryId = savedInstanceState.getInt(STATE_KEY_FACTORY_ITEM);
} else {
mSelectedFactoryId = determineInitialPage();
}
mFactory = getFactoryForItem(mSelectedFactoryId);
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(mFactory.getTitleResId());
getSupportLoaderManager().initLoader(0, null, mUserCallback);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_KEY_FACTORY_ITEM, mSelectedFactoryId);
mFactory.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
mFactory.onRestoreInstanceState(savedInstanceState);
}
}
@Override
public void onClick(View view) {
updateDrawerMode(!mDrawerInAccountMode);
}
@Override
protected int getLeftNavigationDrawerMenuResource() {
return R.menu.home_nav_drawer;
}
@Override
protected int getInitialLeftDrawerSelection(Menu menu) {
mLeftDrawerMenu = menu;
return mSelectedFactoryId;
}
@Override
protected int[] getRightNavigationDrawerMenuResources() {
return mFactory.getToolDrawerMenuResIds();
}
@Override
protected int getInitialRightDrawerSelection() {
return mFactory.getInitialToolDrawerSelection();
}
@Override
protected void onPrepareRightNavigationDrawerMenu(Menu menu) {
super.onPrepareRightNavigationDrawerMenu(menu);
mFactory.prepareToolDrawerMenu(menu);
}
@Override
protected void configureLeftDrawerHeader(View header) {
super.configureLeftDrawerHeader(header);
mAvatarView = (ImageView) header.findViewById(R.id.avatar);
mUserExtraView = (TextView) header.findViewById(R.id.user_extra);
TextView userNameView = (TextView) header.findViewById(R.id.user_name);
userNameView.setText(mUserLogin);
updateUserInfo();
mDrawerSwitcher = (ImageView) header.findViewById(R.id.switcher);
mDrawerSwitcher.setVisibility(View.VISIBLE);
mDrawerSwitcher.setOnClickListener(this);
View clickableBackground = header.findViewById(R.id.drawer_header);
clickableBackground.setOnClickListener(this);
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
super.onNavigationItemSelected(item);
if (mFactory != null && mFactory.onDrawerItemSelected(item)) {
return true;
}
int id = item.getItemId();
FragmentFactory factory = getFactoryForItem(id);
if (factory != null) {
switchTo(id, factory);
return true;
}
switch (id) {
case R.id.profile:
startActivity(UserActivity.makeIntent(this, mUserLogin));
updateDrawerMode(false);
return true;
case R.id.logout:
Gh4Application.get().logout();
goToToplevelActivity();
finish();
return true;
case R.id.add_account:
new BrowserLogoutDialogFragment().show(getSupportFragmentManager(), "browserlogout");
return true;
case R.id.settings:
startActivityForResult(new Intent(this, SettingsActivity.class), REQUEST_SETTINGS);
return true;
}
int accountCount = Gh4Application.get().getAccounts().size();
if (id >= OTHER_ACCOUNTS_GROUP_BASE_ID && id < OTHER_ACCOUNTS_GROUP_BASE_ID + accountCount) {
switchActiveUser(item.getTitle().toString());
return true;
}
return false;
}
@Override
protected void onDrawerClosed(boolean right) {
super.onDrawerClosed(right);
if (!right) {
updateDrawerMode(false);
}
}
private void switchActiveUser(String login) {
Gh4Application.get().setActiveLogin(login);
mUserLogin = login;
onRefresh();
closeDrawers();
switchTo(mSelectedFactoryId, getFactoryForItem(mSelectedFactoryId));
recreate();
}
private FragmentFactory getFactoryForItem(int id) {
switch (id) {
case R.id.news_feed:
return new NewsFeedFactory(this, mUserLogin);
case R.id.notifications:
return new NotificationListFactory(this);
case R.id.my_repos:
return new RepositoryFactory(this, mUserLogin, getPrefs());
case R.id.my_issues:
return new IssueListFactory(this, mUserLogin, false);
case R.id.my_prs:
return new IssueListFactory(this, mUserLogin, true);
case R.id.my_gists:
return new GistFactory(this, mUserLogin);
case R.id.search:
return new SearchFactory(this);
case R.id.bookmarks:
return new BookmarkFactory(this);
case R.id.pub_timeline:
return new TimelineFactory(this);
case R.id.blog:
return new BlogFactory(this);
case R.id.trend:
return new TrendingFactory(this);
}
return null;
}
@Override
protected int[] getTabTitleResIds() {
return mFactory.getTabTitleResIds();
}
@Override
protected int[] getHeaderColorAttrs() {
return mFactory.getHeaderColorAttrs();
}
@Override
protected Fragment makeFragment(int position) {
return mFactory.makeFragment(position);
}
@Override
protected void onFragmentInstantiated(Fragment f, int position) {
mFactory.onFragmentInstantiated(f, position);
}
@Override
protected void onFragmentDestroyed(Fragment f) {
mFactory.onFragmentDestroyed(f);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (mFactory.onCreateOptionsMenu(menu)) {
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mFactory.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SETTINGS) {
if (data.getBooleanExtra(SettingsActivity.RESULT_EXTRA_THEME_CHANGED, false)) {
goToToplevelActivity();
finish();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
protected Intent navigateUp() {
return getToplevelActivityIntent();
}
@Override
public void onRefresh() {
forceLoaderReload(0);
mFactory.onRefresh();
super.onRefresh();
}
@Override
public void supportInvalidateOptionsMenu() {
//noinspection StatementWithEmptyBody
if (mFactory instanceof RepositoryFactory) {
// happens when load is done; we ignore it as we don't want to close the IME in that case
} else {
super.supportInvalidateOptionsMenu();
}
}
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (!closeDrawers() && fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
@Override
public void initiateFilter() {
toggleRightSideDrawer();
}
@Override
protected boolean fragmentNeedsRefresh(Fragment object) {
return true;
}
public void doInvalidateOptionsMenuAndToolDrawer() {
super.supportInvalidateOptionsMenu();
updateRightNavigationDrawer();
}
@Override
public void invalidateTabs() {
super.invalidateTabs();
}
@Override
public void invalidateFragments() {
super.invalidateFragments();
}
public void toggleToolDrawer() {
toggleRightSideDrawer();
}
public void invalidateTitle() {
getSupportActionBar().setTitle(mFactory.getTitleResId());
}
private int determineInitialPage() {
String initialPage = getPrefs().getString(SettingsFragment.KEY_START_PAGE, "newsfeed");
if (TextUtils.equals(initialPage, "last")) {
initialPage = getPrefs().getString("last_selected_home_page", "newsfeed");
}
for (int i = 0; i < START_PAGE_MAPPING.size(); i++) {
if (TextUtils.equals(initialPage, START_PAGE_MAPPING.valueAt(i))) {
return START_PAGE_MAPPING.keyAt(i);
}
}
return R.id.news_feed;
}
private void updateUserInfo() {
if (mUserInfo == null) {
mAvatarView.setImageDrawable(new AvatarHandler.DefaultAvatarDrawable(this, mUserLogin));
return;
}
if (mAvatarView != null) {
AvatarHandler.assignAvatar(mAvatarView, mUserInfo);
}
if (mUserExtraView != null) {
if (TextUtils.isEmpty(mUserInfo.getName())) {
mUserExtraView.setVisibility(View.GONE);
} else {
mUserExtraView.setText(mUserInfo.getName());
mUserExtraView.setVisibility(View.VISIBLE);
}
}
mFactory.setUserInfo(mUserInfo);
}
private void updateDrawerMode(boolean accountMode) {
mLeftDrawerMenu.setGroupVisible(R.id.my_items, !accountMode);
mLeftDrawerMenu.setGroupVisible(R.id.navigation, !accountMode);
mLeftDrawerMenu.setGroupVisible(R.id.explore, !accountMode);
mLeftDrawerMenu.setGroupVisible(R.id.settings, !accountMode);
mLeftDrawerMenu.setGroupVisible(R.id.account, accountMode);
mLeftDrawerMenu.setGroupVisible(R.id.other_accounts, accountMode);
if (accountMode) {
// repopulate other account list
for (int i = 0; ; i++) {
MenuItem item = mLeftDrawerMenu.findItem(OTHER_ACCOUNTS_GROUP_BASE_ID + i);
if (item == null) {
break;
}
mLeftDrawerMenu.removeItem(item.getItemId());
}
int id = OTHER_ACCOUNTS_GROUP_BASE_ID;
SparseArray<String> accounts = Gh4Application.get().getAccounts();
for (int i = 0; i < accounts.size(); i++) {
String login = accounts.valueAt(i);
if (ApiHelpers.loginEquals(mUserLogin, login)) {
continue;
}
MenuItem item = mLeftDrawerMenu.add(R.id.other_accounts, id++, Menu.NONE, login);
AvatarHandler.assignAvatar(this, item, login, accounts.keyAt(i), null);
}
}
mDrawerSwitcher.setImageResource(accountMode
? R.drawable.drop_up_arrow : R.drawable.drop_down_arrow);
mDrawerInAccountMode = accountMode;
}
private void switchTo(int itemId, FragmentFactory factory) {
if (mFactory != null) {
mFactory.onDestroy();
}
mFactory = factory;
mSelectedFactoryId = itemId;
mFactory.setUserInfo(mUserInfo);
getPrefs().edit()
.putString("last_selected_home_page", START_PAGE_MAPPING.get(mSelectedFactoryId))
.apply();
updateRightNavigationDrawer();
super.supportInvalidateOptionsMenu();
getSupportFragmentManager().popBackStackImmediate(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
invalidateTitle();
invalidateTabs();
}
public static class BrowserLogoutDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.browser_logout_dialog_title)
.setMessage(R.string.browser_logout_dialog_text)
.setPositiveButton(R.string.go_to_logout_page, this)
.setNeutralButton(R.string.continue_login, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEUTRAL) {
Github4AndroidActivity.launchLogin(getActivity());
} else if (which == DialogInterface.BUTTON_POSITIVE) {
Uri uri = Uri.parse("https://github.com/logout");
FragmentManager fm = getActivity().getSupportFragmentManager();
IntentUtils.openInCustomTabOrBrowser(getActivity(), uri);
new BrowserLogoutCompletedDialogFragment().show(fm, "browserlogoutcomplete");
}
}
}
public static class BrowserLogoutCompletedDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage(R.string.browser_logout_completed_dialog_text)
.setPositiveButton(R.string.continue_login, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
Github4AndroidActivity.launchLogin(getActivity());
}
}
}