package com.alorma.github.ui.fragment.issues;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.Spinner;
import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.alorma.github.R;
import com.alorma.github.injector.component.ApiComponent;
import com.alorma.github.injector.component.ApplicationComponent;
import com.alorma.github.injector.component.DaggerApiComponent;
import com.alorma.github.injector.module.ApiModule;
import com.alorma.github.injector.module.issues.IssuesModule;
import com.alorma.github.presenter.issue.IssuesPresenter;
import com.alorma.github.sdk.bean.info.IssueInfo;
import com.alorma.github.sdk.bean.info.RepoInfo;
import com.alorma.github.ui.activity.IssueDetailActivity;
import com.alorma.github.ui.activity.NewIssueActivity;
import com.alorma.github.ui.activity.PullRequestDetailActivity;
import com.alorma.github.ui.activity.SearchIssuesActivity;
import com.alorma.github.ui.adapter.base.RecyclerArrayAdapter;
import com.alorma.github.ui.fragment.base.LoadingListFragment;
import com.alorma.github.ui.fragment.detail.repo.BackManager;
import com.alorma.github.ui.fragment.detail.repo.PermissionsManager;
import com.alorma.github.ui.fragment.issues.user.IssuesAdapter;
import com.alorma.github.ui.utils.SimpleItemSelectedItemListener;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.octicons_typeface_library.Octicons;
import core.search.IssuesSearchRequest;
import core.issues.Issue;
import core.repositories.Permissions;
import java.util.List;
import javax.inject.Inject;
public class RepositoryIssuesListFragment extends LoadingListFragment<IssuesAdapter>
implements PermissionsManager, BackManager, com.alorma.github.presenter.View<List<Issue>>, RecyclerArrayAdapter.ItemCallback<Issue> {
@Inject IssuesPresenter presenter;
private static final String REPO_INFO = "REPO_INFO";
private static final int ISSUE_REQUEST = 1234;
private RepoInfo repoInfo;
private Integer currentFilter = null;
@BindView(R.id.showPullRequest) CompoundButton showPullRequest;
@BindView(R.id.revealView) View revealView;
@BindView(R.id.spinner) Spinner spinner;
@BindArray(R.array.issues_filter) String[] issueFilters;
public static RepositoryIssuesListFragment newInstance(RepoInfo repoInfo) {
Bundle bundle = new Bundle();
bundle.putParcelable(REPO_INFO, repoInfo);
RepositoryIssuesListFragment fragment = new RepositoryIssuesListFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.issues_list_fragment, null, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, issueFilters);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new SimpleItemSelectedItemListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (currentFilter == null || currentFilter != position) {
currentFilter = position;
IssuesSearchRequest request = getIssueSearchRequest(position);
presenter.execute(request);
}
}
});
showPullRequest.setOnCheckedChangeListener((compoundButton, b) -> {
IssuesSearchRequest request = getIssueSearchRequest(currentFilter);
presenter.execute(request);
checkFAB();
});
}
@Override
protected void injectComponents(ApplicationComponent applicationComponent) {
super.injectComponents(applicationComponent);
ApiComponent apiComponent = DaggerApiComponent.builder().applicationComponent(applicationComponent).apiModule(new ApiModule()).build();
apiComponent.plus(new IssuesModule()).inject(this);
presenter.attachView(this);
}
@Override
public void onStop() {
presenter.detachView();
super.onStop();
}
@Override
protected int getLightTheme() {
return R.style.AppTheme_Repository;
}
@Override
protected int getDarkTheme() {
return R.style.AppTheme_Dark_Repository;
}
@Override
public void onStart() {
super.onStart();
if (revealView != null) {
revealView.setVisibility(View.INVISIBLE);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.issue_list_filter, menu);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.action_search)
.setIcon(
new IconicsDrawable(this.getContext(), GoogleMaterial.Icon.gmd_search).color(Color.WHITE).sizeDp(24).respectFontBounds(true));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
Intent intent = SearchIssuesActivity.launchIntent(getActivity(), repoInfo);
startActivity(intent);
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void loadArguments() {
if (getArguments() != null) {
repoInfo = getArguments().getParcelable(REPO_INFO);
}
}
@Override
protected void executeRequest() {
if (currentFilter == 0 || currentFilter == 1) {
IssuesSearchRequest builder = getIssueSearchRequest(currentFilter);
presenter.execute(builder);
}
}
@Override
protected boolean autoStart() {
return false;
}
@Override
protected void executePaginatedRequest(int page) {
if (currentFilter == 0 || currentFilter == 1) {
IssuesSearchRequest builder = getIssueSearchRequest(currentFilter);
presenter.executePaginated(builder);
}
}
@NonNull
private IssuesSearchRequest getIssueSearchRequest(Integer status) {
IssuesSearchRequest builder = new IssuesSearchRequest();
builder.setIsOpen(status == null || status == 0);
builder.setRepo(repoInfo.name, repoInfo.owner);
builder.setIsPullRequest(showPullRequest.isChecked());
return builder;
}
protected void onResponse(List<Issue> issues) {
if (issues.size() > 0) {
hideEmpty();
if (refreshing || getAdapter() == null) {
IssuesAdapter issuesAdapter = new IssuesAdapter(LayoutInflater.from(getActivity()));
issuesAdapter.addAll(issues);
issuesAdapter.setCallback(this);
setAdapter(issuesAdapter);
} else {
getAdapter().addAll(issues);
}
} else if (getAdapter() == null || getAdapter().getItemCount() == 0) {
setEmpty();
} else {
getAdapter().clear();
setEmpty();
}
}
@Override
protected Octicons.Icon getNoDataIcon() {
return Octicons.Icon.oct_issue_opened;
}
@Override
protected int getNoDataText() {
return R.string.no_issues_found;
}
@Override
protected boolean useFAB() {
if (showPullRequest == null) {
return repoInfo.permissions != null && repoInfo.permissions.pull;
} else {
return !showPullRequest.isChecked() || repoInfo.permissions != null && repoInfo.permissions.pull;
}
}
@Override
protected void fabClick() {
super.fabClick();
if (repoInfo.permissions != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && fab != null) {
animateRevealFab();
} else {
openNewIssueActivity();
}
}
}
private void openNewIssueActivity() {
Intent intent = NewIssueActivity.createLauncherIntent(getActivity(), repoInfo);
startActivityForResult(intent, ISSUE_REQUEST);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void animateRevealFab() {
float x = fab.getX() + (fab.getWidth() / 2);
float y = fab.getY() + (fab.getHeight() / 2);
int finalRadius = Math.max(revealView.getWidth(), revealView.getHeight());
Animator anim = ViewAnimationUtils.createCircularReveal(revealView, (int) x, (int) y, fab.getWidth() / 2, finalRadius);
revealView.setVisibility(View.VISIBLE);
anim.setDuration(600);
anim.setInterpolator(new AccelerateInterpolator());
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
openNewIssueActivity();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
anim.start();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_FIRST_USER) {
executeRequest();
} else if (requestCode == ISSUE_REQUEST && resultCode == Activity.RESULT_OK) {
executeRequest();
}
}
public void setPermissions(Permissions permissions) {
if (this.repoInfo != null) {
this.repoInfo.permissions = permissions;
checkFAB();
}
}
@Override
protected Octicons.Icon getFABGithubIcon() {
return Octicons.Icon.oct_bug;
}
public void clear() {
if (getAdapter() != null) {
getAdapter().clear();
}
}
@Override
public void setPermissions(boolean admin, boolean push, boolean pull) {
if (this.repoInfo != null) {
Permissions permissions = new Permissions();
permissions.admin = admin;
permissions.push = push;
permissions.pull = pull;
setPermissions(permissions);
}
}
@Override
public boolean onBackPressed() {
return true;
}
@Override
public void setRefreshing() {
super.setRefreshing();
executeRequest();
}
@Override
public void showLoading() {
swipe.setRefreshing(true);
}
@Override
public void hideLoading() {
swipe.setRefreshing(false);
}
@Override
public void onDataReceived(List<Issue> data, boolean isFromPaginated) {
hideEmpty();
if (!isFromPaginated) {
clear();
}
onResponse(data);
}
@Override
public void showError(Throwable throwable) {
setEmpty();
}
@Override
public void onItemSelected(Issue item) {
if (item != null) {
IssueInfo info = new IssueInfo();
info.repoInfo = repoInfo;
info.num = item.getNumber();
if (item.getPullRequest() == null) {
Intent intent = IssueDetailActivity.createLauncherIntent(getActivity(), info);
startActivityForResult(intent, ISSUE_REQUEST);
} else {
Intent intent = PullRequestDetailActivity.createLauncherIntent(getActivity(), info);
startActivityForResult(intent, ISSUE_REQUEST);
}
}
}
}