package com.fastaccess.ui.modules.filter.issues;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.fastaccess.R;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.helper.ActivityHelper;
import com.fastaccess.helper.AnimHelper;
import com.fastaccess.helper.AppHelper;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.Bundler;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.ViewHelper;
import com.fastaccess.ui.adapter.LabelsAdapter;
import com.fastaccess.ui.adapter.MilestonesAdapter;
import com.fastaccess.ui.adapter.SimpleListAdapter;
import com.fastaccess.ui.adapter.UsersAdapter;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.modules.filter.issues.fragment.FilterIssueFragment;
import com.fastaccess.ui.widgets.FontEditText;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.ForegroundImageView;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
import java.util.Arrays;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnEditorAction;
import butterknife.OnTextChanged;
import es.dmoral.toasty.Toasty;
import icepick.State;
/**
* Created by Kosh on 09 Apr 2017, 6:23 PM
*/
public class FilterIssuesActivity extends BaseActivity<FilterIssuesActivityMvp.View, FilterIssuesActivityPresenter> implements
FilterIssuesActivityMvp.View {
@BindView(R.id.back) ForegroundImageView back;
@BindView(R.id.open) FontTextView open;
@BindView(R.id.close) FontTextView close;
@BindView(R.id.author) FontTextView author;
@BindView(R.id.labels) FontTextView labels;
@BindView(R.id.milestone) FontTextView milestone;
@BindView(R.id.assignee) FontTextView assignee;
@BindView(R.id.sort) FontTextView sort;
@BindView(R.id.searchEditText) FontEditText searchEditText;
@BindView(R.id.clear) View clear;
@State boolean isIssue;
@State boolean isOpen;
@State String login;
@State String repoId;
private FilterIssueFragment filterFragment;
private MilestonesAdapter milestonesAdapter;
private LabelsAdapter labelsAdapter;
private UsersAdapter assigneesAdapter;
private PopupWindow popupWindow;
public static void startActivity(@NonNull Activity context, @NonNull String login, @NonNull String repoId,
boolean isIssue, boolean isOpen) {
Intent intent = new Intent(context, FilterIssuesActivity.class);
intent.putExtras(Bundler.start()
.put(BundleConstant.EXTRA, login)
.put(BundleConstant.ID, repoId)
.put(BundleConstant.EXTRA_TWO, isIssue)
.put(BundleConstant.EXTRA_THREE, isOpen)
.end());
View view = context.findViewById(R.id.fab);
if (view != null) {
ActivityHelper.startReveal(context, intent, view);
} else {
context.startActivity(intent);
}
}
@Override protected int layout() {
return R.layout.filter_issues_prs_layout;
}
@Override protected boolean isTransparent() {
return true;
}
@Override protected boolean canBack() {
return true;
}
@Override protected boolean isSecured() {
return false;
}
@NonNull @Override public FilterIssuesActivityPresenter providePresenter() {
return new FilterIssuesActivityPresenter();
}
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Bundle bundle = getIntent().getExtras();
isIssue = bundle.getBoolean(BundleConstant.EXTRA_TWO);
isOpen = bundle.getBoolean(BundleConstant.EXTRA_THREE);
repoId = bundle.getString(BundleConstant.ID);
login = bundle.getString(BundleConstant.EXTRA);
getPresenter().onStart(login, repoId);
if (isOpen) {
onOpenClicked();
} else {
onCloseClicked();
}
}
}
@OnClick(R.id.back) public void onBackClicked() {
onBackPressed();
}
@OnClick(R.id.open) public void onOpenClicked() {
if (!open.isSelected()) {
open.setSelected(true);
close.setSelected(false);
String text = InputHelper.toString(searchEditText);
if (!InputHelper.isEmpty(text)) {
text = text.replace("is:closed", "is:open");
searchEditText.setText(text);
onSearch();
} else {
searchEditText.setText(String.format("%s %s", isOpen ? "is:open" : "is:closed", isIssue ? "is:issue" : "is:pr"));
onSearch();
}
}
}
@OnClick(R.id.close) public void onCloseClicked() {
if (!close.isSelected()) {
open.setSelected(false);
close.setSelected(true);
String text = InputHelper.toString(searchEditText);
if (!InputHelper.isEmpty(text)) {
text = text.replace("is:open", "is:closed");
searchEditText.setText(text);
onSearch();
} else {
searchEditText.setText(String.format("%s %s", isOpen ? "is:open" : "is:closed", isIssue ? "is:issue" : "is:pr"));
onSearch();
}
}
}
@OnClick(R.id.author) public void onAuthorClicked() {
Toasty.info(this, "GitHub doesn't have this API yet!\nYou can try typing it yourself for example author:k0shk0sh",
Toast.LENGTH_LONG).show();
}
@SuppressLint("InflateParams") @OnClick(R.id.labels) public void onLabelsClicked() {
ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
popupWindow = new PopupWindow(this);
popupWindow.setContentView(viewHolder.view);
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
viewHolder.recycler.setAdapter(getLabelsAdapter());
AnimHelper.revealPopupWindow(popupWindow, labels);
}
@SuppressLint("InflateParams") @OnClick(R.id.milestone) public void onMilestoneClicked() {
ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
popupWindow = new PopupWindow(this);
popupWindow.setContentView(viewHolder.view);
popupWindow.setOutsideTouchable(true);
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
viewHolder.recycler.setAdapter(getMilestonesAdapter());
AnimHelper.revealPopupWindow(popupWindow, milestone);
}
@SuppressLint("InflateParams") @OnClick(R.id.assignee) public void onAssigneeClicked() {
ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
popupWindow = new PopupWindow(this);
popupWindow.setContentView(viewHolder.view);
popupWindow.setOutsideTouchable(true);
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
viewHolder.recycler.setAdapter(getAssigneesAdapter());
AnimHelper.revealPopupWindow(popupWindow, assignee);
}
@SuppressLint("InflateParams") @OnClick(R.id.sort) public void onSortClicked() {
ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
popupWindow = new PopupWindow(this);
popupWindow.setContentView(viewHolder.view);
popupWindow.setOutsideTouchable(true);
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
viewHolder.recycler.setAdapter(new SimpleListAdapter<>(Arrays.asList(getResources().getStringArray(R.array.sort_prs_issues)),
new BaseViewHolder.OnItemClickListener<String>() {
@Override public void onItemClick(int position, View v, String item) {
appendSort(item);
}
@Override public void onItemLongClick(int position, View v, String item) {}
}));
AnimHelper.revealPopupWindow(popupWindow, assignee);
}
@Override public void onSetCount(int count, boolean isOpen) {
if (isOpen) {
open.setText(SpannableBuilder.builder()
.append(getString(R.string.open))
.append("(")
.append(String.valueOf(count))
.append(")"));
close.setText(R.string.closed);
} else {
close.setText(SpannableBuilder.builder()
.append(getString(R.string.closed))
.append("(")
.append(String.valueOf(count))
.append(")"));
open.setText(R.string.open);
}
}
@Override public void showProgress(int resId) {
super.showProgress(resId);
}
@Override public void hideProgress() {
super.hideProgress();
}
@OnTextChanged(value = R.id.searchEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) void onTextChange(Editable s) {
String text = s.toString();
if (text.length() == 0) {
AnimHelper.animateVisibility(clear, false);
} else {
AnimHelper.animateVisibility(clear, true);
}
}
@OnClick(value = {R.id.clear}) void onClear(View view) {
if (view.getId() == R.id.clear) {
AppHelper.hideKeyboard(searchEditText);
searchEditText.setText("");
}
}
@OnEditorAction(R.id.searchEditText) boolean onEditor(int actionId, KeyEvent keyEvent) {
if (keyEvent != null && keyEvent.getAction() == KeyEvent.KEYCODE_SEARCH) {
onSearch();
} else if (actionId == EditorInfo.IME_ACTION_SEARCH) {
onSearch();
}
return false;
}
@NonNull private String getRepoName() {
return "repo:" + login + "/" + repoId + " ";
}// let users stay within selected repo context.
@Override public void onBackPressed() {
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
} else {
super.onBackPressed();
}
}
private void onSearch() {
if (!InputHelper.isEmpty(searchEditText)) {
getFilterFragment().onSearch(getRepoName() + InputHelper.toString(searchEditText), open.isSelected(), isIssue);
searchEditText.setSelection(searchEditText.getEditableText().length());
} else {
getFilterFragment().onClear();
showErrorMessage(getString(R.string.empty_search_error));
}
}
private FilterIssueFragment getFilterFragment() {
if (filterFragment == null) {
filterFragment = (FilterIssueFragment) getSupportFragmentManager().findFragmentById(R.id.filterFragment);
}
return filterFragment;
}
private MilestonesAdapter getMilestonesAdapter() {
if (milestonesAdapter == null) {
if (!getPresenter().getMilestones().isEmpty()) {
MilestoneModel milestone = new MilestoneModel();
milestone.setTitle(getString(R.string.clear));
getPresenter().getMilestones().add(0, milestone);
}
milestonesAdapter = new MilestonesAdapter(getPresenter().getMilestones());
milestonesAdapter.setListener(new BaseViewHolder.OnItemClickListener<MilestoneModel>() {
@Override public void onItemClick(int position, View v, MilestoneModel item) {
appendMilestone(item);
}
@Override public void onItemLongClick(int position, View v, MilestoneModel item) {
}
});
}
return milestonesAdapter;
}
private LabelsAdapter getLabelsAdapter() {
if (labelsAdapter == null) {
if (!getPresenter().getLabels().isEmpty()) {
LabelModel label = new LabelModel();
label.setName(getString(R.string.clear));
getPresenter().getLabels().add(0, label);
}
labelsAdapter = new LabelsAdapter(getPresenter().getLabels(), null);
labelsAdapter.setListener(new BaseViewHolder.OnItemClickListener<LabelModel>() {
@Override public void onItemClick(int position, View v, LabelModel item) {
appendLabel(item);
}
@Override public void onItemLongClick(int position, View v, LabelModel item) {
}
});
}
return labelsAdapter;
}
private UsersAdapter getAssigneesAdapter() {
if (assigneesAdapter == null) {
if (!getPresenter().getAssignees().isEmpty()) {
User user = new User();
user.setLogin(getString(R.string.clear));
getPresenter().getAssignees().add(0, user);
}
assigneesAdapter = new UsersAdapter(getPresenter().getAssignees(), false, true);
assigneesAdapter.setListener(new BaseViewHolder.OnItemClickListener<User>() {
@Override public void onItemClick(int position, View v, User item) {
appendAssignee(item);
}
@Override public void onItemLongClick(int position, View v, User item) {}
});
}
return assigneesAdapter;
}
private void appendIfEmpty() {
if (InputHelper.isEmpty(searchEditText))
if (open.isSelected()) {
searchEditText.setText(isIssue ? "is:issue is:open " : "is:pr is:open ");
} else if (close.isSelected()) {
searchEditText.setText(isIssue ? "is:issue is:close " : "is:pr is:close ");
} else {
searchEditText.setText(isIssue ? "is:issue is:open " : "is:pr is:open ");
}
}
private void appendMilestone(MilestoneModel item) {
if (popupWindow != null) {
popupWindow.dismiss();
}
appendIfEmpty();
String text = InputHelper.toString(searchEditText);
String regex = "milestone:(\".+\"|\\S+)";
if (item.getTitle().equalsIgnoreCase(getString(R.string.clear))) {
text = text.replaceAll(regex, "");
searchEditText.setText(text);
onSearch();
return;
}
if (!text.replaceAll(regex, "milestone:\"" + item.getTitle() + "\"").equalsIgnoreCase(text)) {
String space = text.endsWith(" ") ? "" : " ";
text = text.replaceAll(regex, space + "milestone:\"" + item.getTitle() + "\"");
} else {
text += text.endsWith(" ") ? "" : " ";
text += "milestone:\"" + item.getTitle() + "\"";
}
searchEditText.setText(text);
onSearch();
}
private void appendLabel(LabelModel item) {
if (popupWindow != null) {
popupWindow.dismiss();
}
appendIfEmpty();
String text = InputHelper.toString(searchEditText);
String regex = "label:(\".+\"|\\S+)";
if (item.getName().equalsIgnoreCase(getString(R.string.clear))) {
text = text.replaceAll(regex, "");
searchEditText.setText(text);
onSearch();
return;
}
if (!text.replaceAll(regex, "label:\"" + item.getName() + "\"").equalsIgnoreCase(text)) {
String space = text.endsWith(" ") ? "" : " ";
text = text.replaceAll(regex, space + "label:\"" + item.getName() + "\"");
} else {
text += text.endsWith(" ") ? "" : " ";
text += "label:\"" + item.getName() + "\"";
}
searchEditText.setText(text);
onSearch();
}
private void appendAssignee(User item) {
if (popupWindow != null) {
popupWindow.dismiss();
}
appendIfEmpty();
String text = InputHelper.toString(searchEditText);
String regex = "assignee:(\".+\"|\\S+)";
if (item.getLogin().equalsIgnoreCase(getString(R.string.clear))) {
text = text.replaceAll(regex, "");
searchEditText.setText(text);
onSearch();
return;
}
if (!text.replaceAll(regex, "assignee:\"" + item.getLogin() + "\"").equalsIgnoreCase(text)) {
String space = text.endsWith(" ") ? "" : " ";
text = text.replaceAll(regex, space + "assignee:\"" + item.getLogin() + "\"");
} else {
text += text.endsWith(" ") ? "" : " ";
text += "assignee:\"" + item.getLogin() + "\"";
}
searchEditText.setText(text);
onSearch();
}
private void appendSort(String item) {
dismissPopup();
appendIfEmpty();
Resources resources = getResources();
String regex = "sort:(\".+\"|\\S+)";
String oldestQuery = "created-asc";
String mostCommentedQuery = "comments-desc";
String leastCommentedQuery = "comments-asc";
String recentlyUpdatedQuery = "updated-desc";
String leastRecentUpdatedQuery = "updated-asc";
String toQuery = "";
String text = InputHelper.toString(searchEditText);
if (item.equalsIgnoreCase(resources.getString(R.string.newest))) {
text = text.replaceAll(regex, "");
if (!InputHelper.toString(searchEditText).equalsIgnoreCase(text)) {
searchEditText.setText(text);
onSearch();
}
return;
}
if (item.equalsIgnoreCase(resources.getString(R.string.oldest))) {
toQuery = oldestQuery;
} else if (item.equalsIgnoreCase(resources.getString(R.string.most_commented))) {
toQuery = mostCommentedQuery;
} else if (item.equalsIgnoreCase(resources.getString(R.string.least_commented))) {
toQuery = leastCommentedQuery;
} else if (item.equalsIgnoreCase(resources.getString(R.string.recently_updated))) {
toQuery = recentlyUpdatedQuery;
} else if (item.equalsIgnoreCase(resources.getString(R.string.least_recent_updated))) {
toQuery = leastRecentUpdatedQuery;
}
if (!text.replaceAll(regex, "sort:\"" + toQuery + "\"").equalsIgnoreCase(text)) {
String space = text.endsWith(" ") ? "" : " ";
text = text.replaceAll(regex, space + "sort:\"" + toQuery + "\"");
} else {
text += text.endsWith(" ") ? "" : " ";
text += "sort:\"" + toQuery + "\"";
}
if (!InputHelper.toString(searchEditText).equalsIgnoreCase(text)) {
searchEditText.setText(text);
onSearch();
}
}
private void dismissPopup() {
if (popupWindow != null) {
popupWindow.dismiss();
}
}
static class ViewHolder {
@BindView(R.id.title) FontTextView title;
@BindView(R.id.recycler) DynamicRecyclerView recycler;
View view;
ViewHolder(View view) {
this.view = view;
ButterKnife.bind(this, view);
title.setVisibility(View.GONE);
}
}
}