package cl.monsoon.s1next.view.internal;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Build;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.view.WindowInsets;
import cl.monsoon.s1next.App;
import cl.monsoon.s1next.R;
import cl.monsoon.s1next.data.User;
import cl.monsoon.s1next.databinding.NavigationViewHeaderBinding;
import cl.monsoon.s1next.view.activity.FavouriteListActivity;
import cl.monsoon.s1next.view.activity.ForumActivity;
import cl.monsoon.s1next.view.activity.HelpActivity;
import cl.monsoon.s1next.view.activity.LoginActivity;
import cl.monsoon.s1next.view.activity.SettingsActivity;
import cl.monsoon.s1next.view.dialog.LoginPromptDialogFragment;
import cl.monsoon.s1next.view.dialog.LogoutDialogFragment;
import cl.monsoon.s1next.view.dialog.ThemeChangeDialogFragment;
import cl.monsoon.s1next.viewmodel.UserViewModel;
/**
* Implements the concrete UI logic for {@link DrawerLayoutDelegate}.
*/
public final class DrawerLayoutDelegateConcrete extends DrawerLayoutDelegate
implements NavigationView.OnNavigationItemSelectedListener {
private final User mUser;
private final UserViewModel mUserViewModel;
public DrawerLayoutDelegateConcrete(FragmentActivity activity, DrawerLayout drawerLayout, NavigationView navigationView) {
super(activity, drawerLayout, navigationView);
mUserViewModel = App.getAppComponent(activity).getUserViewModel();
mUser = mUserViewModel.getUser();
}
@Override
protected void setupNavDrawerItem(DrawerLayout drawerLayout, NavigationView navigationView) {
setupNavDrawerHeader(drawerLayout, navigationView);
navigationView.setNavigationItemSelectedListener(this);
setupNavDrawerItemChecked(navigationView);
}
private void setupNavDrawerHeader(DrawerLayout drawerLayout, NavigationView navigationView) {
NavigationViewHeaderBinding binding = DataBindingUtil.bind(navigationView.getHeaderView(0));
binding.setUserViewModel(mUserViewModel);
// let status bar display over drawer if API >= 21
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// let DrawerLayout draw the insets area for the status bar
mFragmentActivity.getWindow().setStatusBarColor(Color.TRANSPARENT);
// add status bar height to drawer's header
drawerLayout.setOnApplyWindowInsetsListener((v, insets) -> {
int insetsTop = insets.getSystemWindowInsetTop();
ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams)
binding.drawerUserAvatar.getLayoutParams();
marginLayoutParams.topMargin = insetsTop + v.getContext().getResources()
.getDimensionPixelSize(R.dimen.drawer_avatar_margin_top);
// see https://github.com/android/platform_frameworks_support/blob/master/v4/api21/android/support/v4/widget/DrawerLayoutCompatApi21.java#L86
// add DrawerLayout's default View.OnApplyWindowInsetsListener implementation
((DrawerLayout) v).setChildInsets(new WindowInsets(insets), insetsTop > 0);
return insets.consumeSystemWindowInsets();
});
}
// Starts LoginActivity if user hasn't logged in,
// otherwise show LogoutDialogFragment.
binding.drawerHeaderBackground.setOnClickListener(v -> {
if (!LogoutDialogFragment.showLogoutDialogIfNeeded(mFragmentActivity, mUser)) {
closeDrawer(() -> LoginActivity.startLoginActivityForResultMessage(mFragmentActivity));
}
});
binding.drawerUserAvatar.setOnClickListener(v ->
ThemeChangeDialogFragment.showThemeChangeDialog(mFragmentActivity));
}
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
Runnable runnable;
switch (menuItem.getItemId()) {
case R.id.menu_home:
runnable = this::onHomeMenuSelected;
break;
case R.id.menu_favourites:
runnable = this::onFavouritesMenuSelected;
break;
case R.id.menu_settings:
runnable = this::onSettingsMenuSelected;
break;
case R.id.menu_help:
runnable = this::onHelpMenuSelected;
break;
default:
throw new IllegalStateException("Unknown menu item ID: " + menuItem.getItemId() + ".");
}
closeDrawer(runnable::run);
return false;
}
private void setupNavDrawerItemChecked(NavigationView navigationView) {
MenuItem menuItem = null;
Menu menu = navigationView.getMenu();
if (mFragmentActivity instanceof ForumActivity) {
menuItem = menu.findItem(R.id.menu_home);
} else if (mFragmentActivity instanceof FavouriteListActivity) {
menuItem = menu.findItem(R.id.menu_favourites);
}
// SettingsActivity and HelpActivity don't have drawer
// so it's no need to set checked theirs MenuItem
if (menuItem != null) {
menuItem.setChecked(true);
}
}
private void onHomeMenuSelected() {
if (mFragmentActivity instanceof ForumActivity) {
return;
}
Intent intent = new Intent(mFragmentActivity, ForumActivity.class);
// if this activity is not part of this app's task
if (NavUtils.shouldUpRecreateTask(mFragmentActivity, intent)) {
// finish all our Activities in that app
ActivityCompat.finishAffinity(mFragmentActivity);
// create a new task when navigating up with
// a synthesized back stack
TaskStackBuilder.create(mFragmentActivity)
.addNextIntentWithParentStack(intent)
.startActivities();
} else {
// back to ForumActivity (main Activity)
NavUtils.navigateUpTo(mFragmentActivity, intent);
}
}
private void onFavouritesMenuSelected() {
if (mFragmentActivity instanceof FavouriteListActivity) {
return;
}
// Starts FavouriteListActivity if user has logged in,
// otherwise show LoginPromptDialogFragment.
if (!LoginPromptDialogFragment.showLoginPromptDialogIfNeeded(mFragmentActivity, mUser)) {
FavouriteListActivity.startFavouriteListActivity(mFragmentActivity);
}
}
private void onSettingsMenuSelected() {
SettingsActivity.startSettingsActivity(mFragmentActivity);
}
private void onHelpMenuSelected() {
HelpActivity.startHelpActivity(mFragmentActivity);
}
}