package com.alorma.github.ui.activity;
import android.accounts.Account;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ShortcutManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import com.alorma.github.AccountsHelper;
import com.alorma.github.R;
import com.alorma.github.StoreCredentials;
import com.alorma.github.sdk.services.notifications.GetNotificationsClient;
import com.alorma.github.ui.ErrorHandler;
import com.alorma.github.ui.activity.base.BaseActivity;
import com.alorma.github.ui.fragment.GeneralPeopleFragment;
import com.alorma.github.ui.fragment.NavigationFragment;
import com.alorma.github.ui.fragment.donate.DonateActivity;
import com.alorma.github.ui.fragment.events.EventsListFragment;
import com.alorma.github.ui.fragment.events.OrgsEventsListFragment;
import com.alorma.github.ui.fragment.gists.AuthUserGistsFragment;
import com.alorma.github.ui.fragment.gists.AuthUserStarredGistsFragment;
import com.alorma.github.ui.fragment.issues.GeneralIssuesListFragment;
import com.alorma.github.ui.fragment.orgs.OrgsMembersFragment;
import com.alorma.github.ui.fragment.orgs.OrgsReposFragment;
import com.alorma.github.ui.fragment.repos.GeneralReposFragment;
import com.alorma.github.ui.utils.DrawerImage;
import com.alorma.github.utils.AccountUtils;
import com.appsee.Appsee;
import com.mikepenz.actionitembadge.library.ActionItemBadge;
import com.mikepenz.actionitembadge.library.utils.BadgeStyle;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.holder.StringHolder;
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.ExpandableDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.util.DrawerImageLoader;
import com.mikepenz.octicons_typeface_library.Octicons;
import core.User;
import core.notifications.Notification;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MainActivity extends BaseActivity implements NavigationFragment.NavigationCallback {
public static final String NAVIGATION = "NAVIGATION";
private Account selectedAccount;
private Fragment lastUsedFragment;
private Drawer resultDrawer;
private int notificationsSizeCount = 0;
private NavigationFragment navigationFragment;
private AccountHeader accountHeader;
private Map<String, List<IDrawerItem>> drawerItems;
public static void startActivity(Activity context) {
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.generic_toolbar_responsive);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
checkGoodBye();
}
private void checkGoodBye() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
if (preferences.getBoolean("GOOD_BYE", true)) {
Intent intent = new Intent(this, GoodByeActivity.class);
startActivity(intent);
preferences.edit().putBoolean("GOOD_BYE", false).apply();
}
}
@Override
public void onStart() {
super.onStart();
if (resultDrawer == null) {
List<Account> accounts = getAccounts();
if (!accounts.isEmpty()) {
selectedAccount = accounts.get(0);
createDrawer();
selectAccount(selectedAccount);
if (getIntent() != null && getIntent().getExtras() != null && getIntent().getExtras().containsKey(NAVIGATION)) {
String navigation = getIntent().getStringExtra(NAVIGATION);
if (navigation != null) {
if (navigation.equals(getString(R.string.shortcut_id_events))) {
onUserEventsSelected();
} else if (navigation.equals(getString(R.string.shortcut_id_repositories))) {
onReposSelected();
} else if (navigation.equals(getString(R.string.shortcut_id_people))) {
onPeopleSelected();
} else if (navigation.equals(getString(R.string.shortcut_id_issues))) {
onIssuesSelected();
}
} else {
onUserEventsSelected();
}
} else {
onUserEventsSelected();
}
}
}
}
@Override
protected void onStop() {
navigationFragment.setNavigationCallback(null);
super.onStop();
}
private String getUserExtraName(Account account) {
String accountName = getNameFromAccount(account);
String userMail = AccountsHelper.getUserMail(this, account);
String userName = AccountsHelper.getUserName(this, account);
if (!TextUtils.isEmpty(userMail)) {
return userMail;
} else if (!TextUtils.isEmpty(userName)) {
return userName;
}
return accountName;
}
private String getNameFromAccount(Account account) {
return new AccountUtils().getNameFromAccount(account.name);
}
private void createDrawer() {
accountHeader = buildHeader();
DrawerBuilder drawer = new DrawerBuilder();
drawer.withActivity(this);
drawer.withToolbar(getToolbar());
drawer.withAccountHeader(accountHeader, true);
List<IDrawerItem> userItems = getUserDrawerItems();
for (IDrawerItem userItem : userItems) {
drawer.addDrawerItems(userItem);
}
List<IDrawerItem> allProfilesItems = getStickyDrawerItems();
for (IDrawerItem allProfilesItem : allProfilesItems) {
drawer.addStickyDrawerItems(allProfilesItem);
}
Drawer.OnDrawerItemClickListener drawerListener = (view, position, drawerItem) -> {
if (drawerItem != null) {
long identifier = drawerItem.getIdentifier();
switch ((int) identifier) {
case R.id.nav_drawer_notifications:
openNotifications();
break;
case R.id.nav_drawer_settings:
onSettingsSelected();
break;
case R.id.nav_drawer_donate:
onDonateSelected();
break;
case R.id.nav_drawer_sign_out:
signOut();
return true;
}
}
return false;
};
drawer.withOnDrawerItemClickListener(drawerListener);
resultDrawer = drawer.build();
resultDrawer.setSelection(R.id.nav_drawer_events);
}
private List<IDrawerItem> getUserDrawerItems() {
int iconColor = ContextCompat.getColor(this, R.color.icons);
List<IDrawerItem> items = new ArrayList<>();
items.add(new PrimaryDrawerItem().withName(R.string.menu_events)
.withIcon(Octicons.Icon.oct_calendar)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_events)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onUserEventsSelected();
return false;
}));
items.add(new PrimaryDrawerItem().withName(R.string.navigation_general_repositories)
.withIcon(Octicons.Icon.oct_repo)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_repositories)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onReposSelected();
return false;
}));
items.add(new PrimaryDrawerItem().withName(R.string.navigation_people)
.withIcon(Octicons.Icon.oct_organization)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_people)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onPeopleSelected();
return false;
}));
items.add(new PrimaryDrawerItem().withName(R.string.navigation_issues)
.withIcon(Octicons.Icon.oct_issue_opened)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_issues)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onIssuesSelected();
return false;
}));
PrimaryDrawerItem myGistsDrawerItem = new PrimaryDrawerItem().withName(R.string.navigation_my_gists)
.withIdentifier(R.id.nav_drawer_gists)
.withLevel(2)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onGistsSelected();
return false;
});
PrimaryDrawerItem starredGistsDrawerItem = new PrimaryDrawerItem().withName(R.string.navigation_gists_starred)
.withIdentifier(R.id.nav_drawer_gists_starred)
.withLevel(2)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onStarredGistsSelected();
return false;
});
items.add(new ExpandableDrawerItem().withName(R.string.navigation_gists)
.withSubItems(myGistsDrawerItem, starredGistsDrawerItem)
.withIcon(Octicons.Icon.oct_gist)
.withIconColor(iconColor)
.withSelectable(false));
return items;
}
private List<IDrawerItem> getStickyDrawerItems() {
int iconColor = ContextCompat.getColor(this, R.color.icons);
List<IDrawerItem> items = new ArrayList<>();
items.add(new SecondaryDrawerItem().withName(R.string.menu_enable_notifications)
.withIdentifier(R.id.nav_drawer_notifications)
.withSelectable(false)
.withIcon(Octicons.Icon.oct_bell)
.withIconColor(iconColor));
items.add(new SecondaryDrawerItem().withName(R.string.navigation_settings)
.withIcon(Octicons.Icon.oct_gear)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_settings)
.withSelectable(false));
items.add(new SecondaryDrawerItem().withName(R.string.action_donate)
.withIcon(Octicons.Icon.oct_heart)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_donate)
.withSelectable(false));
items.add(new DividerDrawerItem());
items.add(new SecondaryDrawerItem().withName(R.string.navigation_sign_out)
.withIcon(Octicons.Icon.oct_sign_out)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_sign_out)
.withSelectable(false));
return items;
}
private AccountHeader buildHeader() {
DrawerImageLoader.init(new DrawerImage());
AccountHeaderBuilder headerBuilder = new AccountHeaderBuilder().withActivity(this).withHeaderBackground(R.color.md_grey_600);
headerBuilder.withOnAccountHeaderListener((view, profile, current) -> {
if (current) {
User user = new User();
user.setLogin(profile.getName().getText());
Intent launcherIntent = ProfileActivity.createLauncherIntent(MainActivity.this, selectedAccount);
startActivity(launcherIntent);
return true;
} else {
if (profile instanceof ProfileDrawerItem) {
List<IDrawerItem> subItems = drawerItems.get(profile.getName().getText());
if (subItems != null && !subItems.isEmpty()) {
resultDrawer.removeAllItems();
for (IDrawerItem subItem : subItems) {
resultDrawer.addItems(subItem);
}
try {
((PrimaryDrawerItem) subItems.get(0)).getOnDrawerItemClickListener().onItemClick(null, 0, subItems.get(0));
} catch (Exception e) {
e.printStackTrace();
}
resultDrawer.setSelection(R.id.nav_drawer_events, true);
}
}
return false;
}
});
ProfileDrawerItem userDrawerItem = getUserDrawerItem();
drawerItems = new HashMap<>();
drawerItems.put(userDrawerItem.getName().getText(), getUserDrawerItems());
userDrawerItem.withSubItems();
headerBuilder.addProfiles(userDrawerItem);
return headerBuilder.build();
}
@NonNull
private ProfileDrawerItem getOrganizationProfileDrawerItem(User user) {
return new ProfileDrawerItem().withName(user.getLogin()).withIcon(getUserAvatarUrl(user.getAvatar(), user.getLogin()));
}
private Uri getUserAvatarUrl(String avatar, String name) {
return Uri.parse(avatar).buildUpon().appendQueryParameter("username", name).build();
}
private List<IDrawerItem> getOrganizationProfileSubItems(User user) {
int iconColor = ContextCompat.getColor(this, R.color.icons);
List<IDrawerItem> items = new ArrayList<>();
items.add(new PrimaryDrawerItem().withName("Events")
.withIcon(Octicons.Icon.oct_calendar)
.withIconColor(iconColor)
.withIdentifier(R.id.nav_drawer_events)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onOrgEventsSelected(user.getLogin());
return false;
}));
items.add(new PrimaryDrawerItem().withName("Repositories")
.withIcon(Octicons.Icon.oct_repo)
.withIconColor(iconColor)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onOrgReposSelected(user.getLogin());
return false;
}));
items.add(new PrimaryDrawerItem().withName("Members")
.withIcon(Octicons.Icon.oct_organization)
.withIconColor(iconColor)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onOrgPeopleSelected(user.getLogin());
return false;
}));
items.add(new PrimaryDrawerItem().withName("Teams")
.withIcon(Octicons.Icon.oct_jersey)
.withIconColor(iconColor)
.withEnabled(false)
.withOnDrawerItemClickListener((view, position, drawerItem) -> {
onOrgTeamsSelected(user.getLogin());
return false;
}));
return items;
}
private ProfileDrawerItem getUserDrawerItem() {
String userName = getNameFromAccount(selectedAccount);
String userAvatar = AccountsHelper.getUserAvatar(this, selectedAccount);
ProfileDrawerItem userDrawerItem = new ProfileDrawerItem().withName(getUserExtraName(selectedAccount))
.withEmail(userName)
.withNameShown(false)
.withIdentifier(selectedAccount.hashCode());
if (!TextUtils.isEmpty(userAvatar)) {
userDrawerItem.withIcon(getUserAvatarUrl(userAvatar, userName));
}
return userDrawerItem;
}
private void selectAccount(final Account account) {
boolean changingUser = selectedAccount != null && !getNameFromAccount(selectedAccount).equals(getNameFromAccount(account));
this.selectedAccount = account;
Appsee.setUserId(getNameFromAccount(account));
accountNameProvider.setName(getNameFromAccount(account));
loadUserOrgs();
StoreCredentials credentials = new StoreCredentials(MainActivity.this);
credentials.clear();
String authToken = AccountsHelper.getUserToken(this, account);
credentials.storeToken(authToken);
credentials.storeUsername(getNameFromAccount(account));
credentials.storeUrl(AccountsHelper.getUrl(this, account));
String url = AccountsHelper.getUrl(this, account);
credentials.storeUrl(url);
if (changingUser) {
lastUsedFragment = null;
}
}
private void loadUserOrgs() {
navigationFragment = new NavigationFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(new NavigationFragment(), "navigation");
ft.commit();
navigationFragment.setNavigationCallback(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main_menu, menu);
menu.findItem(R.id.action_search)
.setIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_search).color(Color.WHITE).sizeDp(24).respectFontBounds(true));
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (notificationsSizeCount > 0) {
BadgeStyle badgeStyle =
new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, getResources().getColor(R.color.accent),
getResources().getColor(R.color.accent_dark), Color.WHITE, getResources().getDimensionPixelOffset(R.dimen.gapMicro));
ActionItemBadge.update(this, menu.findItem(R.id.action_notifications), Octicons.Icon.oct_bell, badgeStyle, notificationsSizeCount);
} else {
ActionItemBadge.hide(menu.findItem(R.id.action_notifications));
}
return super.onPrepareOptionsMenu(menu);
}
@Override
protected void onResume() {
super.onResume();
checkNotifications();
}
private void checkNotifications() {
GetNotificationsClient client = new GetNotificationsClient();
client.observable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Notification>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Notification> notifications) {
notificationsSizeCount = notifications.size();
invalidateOptionsMenu();
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_search) {
Intent intent = SearchActivity.launchIntent(this);
startActivity(intent);
} else if (item.getItemId() == R.id.action_notifications) {
openNotifications();
}
return false;
}
private void openNotifications() {
Intent intent = NotificationsActivity.launchIntent(this);
startActivity(intent);
}
@TargetApi(Build.VERSION_CODES.M)
private void tagShortcut(@StringRes int shortcutId) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
String id = getString(shortcutId);
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
shortcutManager.reportShortcutUsed(id);
}
}
private void setFragment(Fragment fragment) {
setFragment(fragment, true);
}
private void setFragment(Fragment fragment, boolean addToBackStack) {
try {
if (fragment != null && getSupportFragmentManager() != null) {
this.lastUsedFragment = fragment;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (ft != null) {
ft.replace(R.id.content, fragment);
if (addToBackStack) {
ft.addToBackStack("navigation");
}
ft.commit();
}
}
} catch (Exception e) {
ErrorHandler.onError(this, "MainActivity.setFragment()", e);
}
}
public void onDonateSelected() {
Intent intent = new Intent(this, DonateActivity.class);
startActivity(intent);
}
public boolean onReposSelected() {
setFragment(GeneralReposFragment.newInstance(), false);
tagShortcut(R.string.shortcut_id_repositories);
return true;
}
public boolean onPeopleSelected() {
setFragment(GeneralPeopleFragment.newInstance(), false);
tagShortcut(R.string.shortcut_id_people);
return false;
}
public boolean onIssuesSelected() {
setFragment(GeneralIssuesListFragment.newInstance(), false);
tagShortcut(R.string.shortcut_id_issues);
return false;
}
public boolean onGistsSelected() {
AuthUserGistsFragment gistsFragment = AuthUserGistsFragment.newInstance();
setFragment(gistsFragment);
return false;
}
public boolean onStarredGistsSelected() {
AuthUserStarredGistsFragment gistsFragment = AuthUserStarredGistsFragment.newInstance();
setFragment(gistsFragment);
return false;
}
public boolean onUserEventsSelected() {
String user = new StoreCredentials(this).getUserName();
if (user != null) {
setFragment(EventsListFragment.newInstance(user), false);
}
tagShortcut(R.string.shortcut_id_events);
return true;
}
public void onOrgEventsSelected(String orgName) {
OrgsEventsListFragment orgsEventsListFragment = OrgsEventsListFragment.newInstance(orgName);
setFragment(orgsEventsListFragment, true);
}
public void onOrgReposSelected(String orgName) {
OrgsReposFragment orgsReposFragment = OrgsReposFragment.newInstance(orgName);
setFragment(orgsReposFragment, true);
}
public void onOrgPeopleSelected(String orgName) {
OrgsMembersFragment orgsMembersFragment = OrgsMembersFragment.newInstance(orgName);
setFragment(orgsMembersFragment, true);
}
public void onOrgTeamsSelected(String orgName) {
}
public boolean onSettingsSelected() {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return false;
}
public void signOut() {
if (selectedAccount != null) {
removeAccount(selectedAccount, () -> {
StoreCredentials storeCredentials = new StoreCredentials(MainActivity.this);
storeCredentials.clear();
Intent intent = new Intent(MainActivity.this, SplashActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
});
}
}
@Override
public void onBackPressed() {
if (resultDrawer != null && resultDrawer.isDrawerOpen()) {
resultDrawer.closeDrawer();
} else {
if (lastUsedFragment instanceof EventsListFragment || lastUsedFragment instanceof OrgsEventsListFragment) {
finish();
} else if (resultDrawer != null) {
StringHolder name = accountHeader.getActiveProfile().getEmail();
if (name == null) {
name = accountHeader.getActiveProfile().getName();
}
String nameForAccount = new AccountUtils().getNameFromAccount(selectedAccount.name);
boolean isCurrentUser = nameForAccount != null && nameForAccount.equals(name.getText());
if (isCurrentUser) {
onUserEventsSelected();
} else {
onOrgEventsSelected(name.getText());
}
}
}
}
@Override
public void onOrganizationsLoaded(List<User> organizations) {
if (accountHeader != null) {
for (User organization : organizations) {
ProfileDrawerItem drawerItem = getOrganizationProfileDrawerItem(organization);
if (!drawerItems.containsKey(drawerItem.getName().getText())) {
drawerItems.put(drawerItem.getName().getText(), getOrganizationProfileSubItems(organization));
drawerItem.withSubItems();
accountHeader.addProfiles(drawerItem);
}
}
}
}
}