From 6654ba4abd34426a114b73f3d6f9421a0e7bdba3 Mon Sep 17 00:00:00 2001 From: M M Arif Date: Mon, 4 Apr 2022 09:32:03 +0200 Subject: [PATCH] Filter my issues and use remote search (#1091) Closes #1090 - [x] Filter my issues - [x] Add search to my issues Co-authored-by: M M Arif Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1091 Reviewed-by: qwerty287 --- README.md | 2 +- app/build.gradle | 2 +- .../mian/gitnex/activities/MainActivity.java | 66 ++++++++++----- .../adapters/ExploreRepositoriesAdapter.java | 2 +- .../gitnex/adapters/RepoForksAdapter.java | 2 +- .../gitnex/adapters/ReposListAdapter.java | 2 +- .../adapters/RepositoriesByOrgAdapter.java | 2 +- .../adapters/profile/RepositoriesAdapter.java | 2 +- .../profile/StarredRepositoriesAdapter.java | 2 +- .../BottomSheetMyIssuesFilterFragment.java | 53 ++++++++++++ .../gitnex/fragments/MyIssuesFragment.java | 64 +++++++++++++-- .../gitnex/viewmodels/BranchesViewModel.java | 59 -------------- .../gitnex/viewmodels/IssuesViewModel.java | 15 ++-- .../layout/bottom_sheet_my_issues_filter.xml | 80 +++++++++++++++++++ 14 files changed, 254 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/fragments/BottomSheetMyIssuesFilterFragment.java delete mode 100644 app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java create mode 100644 app/src/main/res/layout/bottom_sheet_my_issues_filter.xml diff --git a/README.md b/README.md index ea568674..d40c959d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Thanks to all the open source libraries, contributors and donators. - [noties/Markwon](https://github.com/noties/Markwon) - [noties/Prism4j](https://github.com/noties/Prism4j) - [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime) -- [amulyakhare/TextDrawable](https://github.com/amulyakhare/TextDrawable) +- [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable) - [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java) - [Pes8/android-material-color-picker-dialog](https://github.com/Pes8/android-material-color-picker-dialog) - [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView) diff --git a/app/build.gradle b/app/build.gradle index 0f625a26..9f44a15b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,7 @@ dependencies { implementation "com.squareup.picasso:picasso:2.71828" implementation 'jp.wasabeef:picasso-transformations:2.4.0' implementation 'jp.co.cyberagent.android:gpuimage:2.1.0' - implementation 'com.github.amulyakhare:TextDrawable:558677ea31' + implementation 'com.github.ramseth001:TextDrawable:1.1.3' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java index 2c76d5c2..601f0c42 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -36,6 +36,7 @@ import org.mian.gitnex.database.models.UserAccount; import org.mian.gitnex.databinding.ActivityMainBinding; import org.mian.gitnex.fragments.AdministrationFragment; import org.mian.gitnex.fragments.BottomSheetDraftsFragment; +import org.mian.gitnex.fragments.BottomSheetMyIssuesFilterFragment; import org.mian.gitnex.fragments.DraftsFragment; import org.mian.gitnex.fragments.ExploreFragment; import org.mian.gitnex.fragments.MyIssuesFragment; @@ -53,6 +54,7 @@ import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.structs.BottomSheetListener; +import org.mian.gitnex.structs.FragmentRefreshListener; import java.util.ArrayList; import java.util.List; import jp.wasabeef.picasso.transformations.BlurTransformation; @@ -81,6 +83,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig private TextView notificationCounter; private BottomSheetListener profileInitListener; + private FragmentRefreshListener fragmentRefreshListenerMyIssues; @Override public void onCreate(Bundle savedInstanceState) { @@ -461,39 +464,51 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig public void onButtonClicked(String text) { int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId"); - if("deleteDrafts".equals(text)) { + switch(text) { - if(currentActiveAccountId > 0) { + case "deleteDrafts": + if(currentActiveAccountId > 0) { - FragmentManager fm = getSupportFragmentManager(); - DraftsFragment frag = (DraftsFragment) fm.findFragmentById(R.id.fragment_container); + FragmentManager fm = getSupportFragmentManager(); + DraftsFragment frag = (DraftsFragment) fm.findFragmentById(R.id.fragment_container); - if(frag != null) { + if(frag != null) { - new AlertDialog.Builder(ctx) - .setTitle(R.string.deleteAllDrafts) - .setIcon(R.drawable.ic_delete) - .setCancelable(false) - .setMessage(R.string.deleteAllDraftsDialogMessage) - .setPositiveButton(R.string.menuDeleteText, (dialog, which) -> { + new AlertDialog.Builder(ctx) + .setTitle(R.string.deleteAllDrafts) + .setIcon(R.drawable.ic_delete) + .setCancelable(false) + .setMessage(R.string.deleteAllDraftsDialogMessage) + .setPositiveButton(R.string.menuDeleteText, (dialog, which) -> { - frag.deleteAllDrafts(currentActiveAccountId); - dialog.dismiss(); + frag.deleteAllDrafts(currentActiveAccountId); + dialog.dismiss(); + + }) + .setNeutralButton(R.string.cancelButton, null).show(); + } + else { + + Toasty.error(ctx, getResources().getString(R.string.genericError)); + } - }) - .setNeutralButton(R.string.cancelButton, null).show(); } else { Toasty.error(ctx, getResources().getString(R.string.genericError)); } + break; - } - else { - - Toasty.error(ctx, getResources().getString(R.string.genericError)); - } - + case "openMyIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("open"); + } + break; + case "closedMyIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("closed"); + } + break; } } @@ -591,6 +606,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig bottomSheet.show(getSupportFragmentManager(), "draftsBottomSheet"); return true; } + else if(id == R.id.filter) { + + BottomSheetMyIssuesFilterFragment filterBottomSheet = new BottomSheetMyIssuesFilterFragment(); + filterBottomSheet.show(getSupportFragmentManager(), "myIssuesFilterMenuBottomSheet"); + return true; + } return super.onOptionsItemSelected(item); } @@ -698,4 +719,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig this.profileInitListener = profileInitListener; } + // My issues-open-close interface + public FragmentRefreshListener getFragmentRefreshListener() { return fragmentRefreshListenerMyIssues; } + public void setFragmentRefreshListenerMyIssues(FragmentRefreshListener fragmentRefreshListener) { this.fragmentRefreshListenerMyIssues = fragmentRefreshListener; } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/ExploreRepositoriesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ExploreRepositoriesAdapter.java index 118a1558..6adf5926 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/ExploreRepositoriesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/ExploreRepositoriesAdapter.java @@ -136,7 +136,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter { + bmListener.onButtonClicked("openMyIssues"); + dismiss(); + }); + + bottomSheetIssuesFilterBinding.closedMyIssues.setOnClickListener(v12 -> { + bmListener.onButtonClicked("closedMyIssues"); + dismiss(); + }); + + return bottomSheetIssuesFilterBinding.getRoot(); + } + + @Override + public void onAttach(@NonNull Context context) { + + super.onAttach(context); + + try { + bmListener = (BottomSheetListener) context; + } + catch(ClassCastException e) { + throw new ClassCastException(context + " must implement BottomSheetListener"); + } + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/MyIssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyIssuesFragment.java index aa1195a4..6d8ac46e 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MyIssuesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MyIssuesFragment.java @@ -4,14 +4,20 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; +import org.mian.gitnex.R; import org.mian.gitnex.activities.BaseActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.ExploreIssuesAdapter; import org.mian.gitnex.databinding.FragmentIssuesBinding; import org.mian.gitnex.viewmodels.IssuesViewModel; @@ -25,11 +31,14 @@ public class MyIssuesFragment extends Fragment { private FragmentIssuesBinding fragmentIssuesBinding; private ExploreIssuesAdapter adapter; private int page = 1; + private Menu menu; + public String state = "open"; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false); + setHasOptionsMenu(true); fragmentIssuesBinding.recyclerView.setHasFixedSize(true); fragmentIssuesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); @@ -37,24 +46,40 @@ public class MyIssuesFragment extends Fragment { DividerItemDecoration.VERTICAL); fragmentIssuesBinding.recyclerView.addItemDecoration(dividerItemDecoration); + ((MainActivity) requireActivity()).setFragmentRefreshListenerMyIssues(myIssuesState -> { + + state = myIssuesState; + if(myIssuesState.equals("open")) { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + + fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE); + fragmentIssuesBinding.noDataIssues.setVisibility(View.GONE); + + fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), null, myIssuesState); + }); + fragmentIssuesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { page = 1; fragmentIssuesBinding.pullToRefresh.setRefreshing(false); - IssuesViewModel.loadIssuesList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), null, "issues", true, "open", getContext()); + IssuesViewModel.loadIssuesList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), null, "issues", true, state, getContext()); fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE); }, 50)); - fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization()); + fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), null, state); return fragmentIssuesBinding.getRoot(); }; - private void fetchDataAsync(String instanceToken) { + private void fetchDataAsync(String instanceToken, String query, String state) { IssuesViewModel issuesModel = new ViewModelProvider(this).get(IssuesViewModel.class); - issuesModel.getIssuesList(instanceToken, "", "issues", true, "open", getContext()).observe(getViewLifecycleOwner(), issuesListMain -> { + issuesModel.getIssuesList(instanceToken, query, "issues", true, state, getContext()).observe(getViewLifecycleOwner(), issuesListMain -> { adapter = new ExploreIssuesAdapter(issuesListMain, getContext()); adapter.setLoadMoreListener(new ExploreIssuesAdapter.OnLoadMoreListener() { @@ -63,7 +88,7 @@ public class MyIssuesFragment extends Fragment { public void onLoadMore() { page += 1; - IssuesViewModel.loadMoreIssues(instanceToken, "", "issues", true, "open", page, getContext(), adapter); + IssuesViewModel.loadMoreIssues(instanceToken, query, "issues", true, state, page, getContext(), adapter); fragmentIssuesBinding.progressBar.setVisibility(View.VISIBLE); } @@ -87,4 +112,33 @@ public class MyIssuesFragment extends Fragment { fragmentIssuesBinding.progressBar.setVisibility(View.GONE); }); } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + + this.menu = menu; + inflater.inflate(R.menu.search_menu, menu); + inflater.inflate(R.menu.filter_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + + MenuItem searchItem = menu.findItem(R.id.action_search); + androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), query, state); + searchView.setQuery(null, false); + searchItem.collapseActionView(); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + return false; + } + }); + } } diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java deleted file mode 100644 index d33128b0..00000000 --- a/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.mian.gitnex.viewmodels; - -import android.content.Context; -import android.util.Log; -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import org.gitnex.tea4j.models.Branches; -import org.mian.gitnex.clients.RetrofitClient; -import java.util.List; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; - -/** - * Author M M Arif - */ - -public class BranchesViewModel extends ViewModel { - - private static MutableLiveData> branchesList; - - public LiveData> getBranchesList(String token, String owner, String repo, Context ctx) { - - branchesList = new MutableLiveData<>(); - loadBranchesList(token, owner, repo, ctx); - - return branchesList; - } - - public static void loadBranchesList(String token, String owner, String repo, Context ctx) { - - Call> call = RetrofitClient - .getApiInterface(ctx) - .getBranches(token, owner, repo); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if (response.isSuccessful()) { - branchesList.postValue(response.body()); - } else { - Log.i("onResponse", String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, Throwable t) { - Log.i("onFailure", t.toString()); - } - - }); - } - -} diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/IssuesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/IssuesViewModel.java index 6bdcd7df..92efe8cd 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/IssuesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/IssuesViewModel.java @@ -7,17 +7,19 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import org.gitnex.tea4j.models.Issues; +import org.mian.gitnex.R; import org.mian.gitnex.activities.BaseActivity; import org.mian.gitnex.adapters.ExploreIssuesAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.Constants; +import org.mian.gitnex.helpers.Toasty; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; /** - * Author M M Arif + * @author M M Arif */ public class IssuesViewModel extends ViewModel { @@ -45,21 +47,22 @@ public class IssuesViewModel extends ViewModel { .getApiInterface(ctx) .queryIssues(token, searchKeyword, type, created, state, resultLimit, 1); - call.enqueue(new Callback>() { + call.enqueue(new Callback<>() { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { - if (response.isSuccessful()) { + if(response.isSuccessful()) { issuesList.postValue(response.body()); } else { - Log.e("onResponse", String.valueOf(response.code())); + Toasty.error(ctx, ctx.getString(R.string.genericError)); } } @Override - public void onFailure(@NonNull Call> call, Throwable t) { + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); } }); @@ -90,7 +93,7 @@ public class IssuesViewModel extends ViewModel { } } else { - Log.e("onResponse", String.valueOf(response.code())); + Toasty.error(ctx, ctx.getString(R.string.genericError)); } } diff --git a/app/src/main/res/layout/bottom_sheet_my_issues_filter.xml b/app/src/main/res/layout/bottom_sheet_my_issues_filter.xml new file mode 100644 index 00000000..c859fc1d --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_my_issues_filter.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +