Extend explore repositories search (#703)

Merge branch 'master' into improve-explore-screen

improve email address input ui

Add filter query actions

Add radio buttons

improve nav accounts list images

Merge branch 'master' into improve-explore-screen

# Conflicts:
#	app/src/main/res/values/strings.xml

Implement dialog and use new input layout

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/703
This commit is contained in:
M M Arif 2020-09-27 09:55:59 +02:00
parent bf19e52799
commit d20a773d1d
9 changed files with 326 additions and 46 deletions

View File

@ -1,10 +1,16 @@
package org.mian.gitnex.fragments;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
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;
@ -18,6 +24,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.ExploreRepositoriesAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.CustomExploreRepositoriesDialogBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.ExploreRepositories;
@ -29,12 +36,14 @@ import retrofit2.Callback;
import retrofit2.Response;
/**
* Template Author Author M M Arif
* Template Author M M Arif
* Author 6543
*/
public class ExploreRepositoriesFragment extends Fragment {
private Context ctx;
private TinyDB tinyDb;
private static String repoNameF = "param2";
private static String repoOwnerF = "param1";
private ProgressBar mProgressBar;
@ -48,6 +57,9 @@ public class ExploreRepositoriesFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private Dialog dialogFilterOptions;
private CustomExploreRepositoriesDialogBinding filterBinding;
public ExploreRepositoriesFragment() {
}
@ -76,13 +88,20 @@ public class ExploreRepositoriesFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_explore_repo, container, false);
//setHasOptionsMenu(true);
setHasOptionsMenu(true);
ctx = getContext();
TinyDB tinyDb = new TinyDB(getContext());
tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
tinyDb.putBoolean("exploreRepoIncludeTopic", false);
tinyDb.putBoolean("exploreRepoIncludeDescription", false);
tinyDb.putBoolean("exploreRepoIncludeTemplate", false);
tinyDb.putBoolean("exploreRepoOnlyArchived", false);
tinyDb.putBoolean("exploreRepoOnlyPrivate", false);
searchKeyword = v.findViewById(R.id.searchKeyword);
noData = v.findViewById(R.id.noData);
mProgressBar = v.findViewById(R.id.progress_bar);
@ -96,7 +115,7 @@ public class ExploreRepositoriesFragment extends Fragment {
if(!searchKeyword.getText().toString().equals("")) {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
loadSearchReposList(instanceUrl, instanceToken, loginUid, searchKeyword.getText().toString(), repoTypeInclude, sort, order, getContext(), limit);
loadSearchReposList(instanceUrl, instanceToken, loginUid, searchKeyword.getText().toString(), repoTypeInclude, sort, order, getContext(), tinyDb.getBoolean("exploreRepoIncludeTopic"), tinyDb.getBoolean("exploreRepoIncludeDescription"), tinyDb.getBoolean("exploreRepoIncludeTemplate"), tinyDb.getBoolean("exploreRepoOnlyArchived"), tinyDb.getBoolean("exploreRepoOnlyPrivate"), limit);
}
}
return false;
@ -111,7 +130,7 @@ public class ExploreRepositoriesFragment extends Fragment {
private void loadDefaultList(String instanceUrl, String instanceToken, String loginUid, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) {
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), null, repoTypeInclude, sort, order, limit);
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), null, repoTypeInclude, sort, order, tinyDb.getBoolean("exploreRepoIncludeTopic"), tinyDb.getBoolean("exploreRepoIncludeDescription"), tinyDb.getBoolean("exploreRepoIncludeTemplate"), tinyDb.getBoolean("exploreRepoOnlyArchived"), tinyDb.getBoolean("exploreRepoOnlyPrivate"), limit);
call.enqueue(new Callback<ExploreRepositories>() {
@ -138,9 +157,9 @@ public class ExploreRepositoriesFragment extends Fragment {
}
private void loadSearchReposList(String instanceUrl, String instanceToken, String loginUid, String searchKeyword, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) {
private void loadSearchReposList(String instanceUrl, String instanceToken, String loginUid, String searchKeyword, Boolean repoTypeInclude, String sort, String order, final Context context, boolean topic, boolean includeDesc, boolean template, boolean onlyArchived, boolean onlyPrivate, int limit) {
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order, limit);
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order, topic, includeDesc, template, onlyArchived, onlyPrivate, limit);
call.enqueue(new Callback<ExploreRepositories>() {
@ -194,6 +213,110 @@ public class ExploreRepositoriesFragment extends Fragment {
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.filter_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem filter = menu.findItem(R.id.filter);
filter.setOnMenuItemClickListener(filter_ -> {
showFilterOptions();
return false;
});
}
private void showFilterOptions() {
dialogFilterOptions = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogFilterOptions.getWindow() != null) {
dialogFilterOptions.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
filterBinding = CustomExploreRepositoriesDialogBinding.inflate(LayoutInflater.from(ctx));
View view = filterBinding.getRoot();
dialogFilterOptions.setContentView(view);
filterBinding.includeTopic.setOnClickListener(includeTopic -> {
if(filterBinding.includeTopic.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeTopic", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeTopic", false);
}
});
filterBinding.includeDesc.setOnClickListener(includeDesc -> {
if(filterBinding.includeDesc.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeDescription", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeDescription", false);
}
});
filterBinding.includeTemplate.setOnClickListener(includeTemplate -> {
if(filterBinding.includeTemplate.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeTemplate", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeTemplate", false);
}
});
filterBinding.onlyArchived.setOnClickListener(onlyArchived -> {
if(filterBinding.onlyArchived.isChecked()) {
tinyDb.putBoolean("exploreRepoOnlyArchived", true);
}
else {
tinyDb.putBoolean("exploreRepoOnlyArchived", false);
}
});
filterBinding.onlyPrivate.setOnClickListener(onlyPrivate -> {
if(filterBinding.onlyPrivate.isChecked()) {
tinyDb.putBoolean("exploreRepoOnlyPrivate", true);
}
else {
tinyDb.putBoolean("exploreRepoOnlyPrivate", false);
}
});
filterBinding.includeTopic.setChecked(tinyDb.getBoolean("exploreRepoIncludeTopic"));
filterBinding.includeDesc.setChecked(tinyDb.getBoolean("exploreRepoIncludeDescription"));
filterBinding.includeTemplate.setChecked(tinyDb.getBoolean("exploreRepoIncludeTemplate"));
filterBinding.onlyArchived.setChecked(tinyDb.getBoolean("exploreRepoOnlyArchived"));
filterBinding.onlyPrivate.setChecked(tinyDb.getBoolean("exploreRepoOnlyPrivate"));
filterBinding.cancel.setOnClickListener(editProperties -> {
dialogFilterOptions.dismiss();
});
dialogFilterOptions.show();
}
public void onButtonPressed(Uri uri) {
if(mListener != null) {

View File

@ -266,7 +266,7 @@ public interface ApiInterface {
Call<List<UserInfo>> getRepoWatchers(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@GET("repos/search") // get all the repos which match the query string
Call<ExploreRepositories> queryRepos(@Header("Authorization") String token, @Query("q") String searchKeyword, @Query("private") Boolean repoTypeInclude, @Query("sort") String sort, @Query("order") String order, @Query("limit") int limit);
Call<ExploreRepositories> queryRepos(@Header("Authorization") String token, @Query("q") String searchKeyword, @Query("private") Boolean repoTypeInclude, @Query("sort") String sort, @Query("order") String order, @Query("topic") boolean topic, @Query("includeDesc") boolean includeDesc, @Query("template") boolean template, @Query("archived") boolean archived, @Query("is_private") boolean is_private, @Query("limit") int limit);
@POST("repos/{owner}/{repo}/contents/{file}") // create new file
Call<JsonElement> createNewFile(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("file") String fileName, @Body NewFile jsonStr);

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="?attr/primaryBackgroundColor">
@ -50,27 +50,30 @@
android:padding="16dp"
android:orientation="vertical">
<TextView
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/userEmailLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/profileEmailTitle"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp" />
<EditText
android:id="@+id/userEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:textSize="14sp"
tools:ignore="Autofill"
android:inputType="textEmailAddress"
android:labelFor="@+id/userEmail"
android:background="@drawable/shape_inputs"
android:textColor="?attr/inputTextColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"/>
app:hintTextColor="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
android:hint="@string/profileEmailTitle">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/userEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/addEmailButton"

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_custom_dialog"
android:orientation="vertical">
<LinearLayout
android:id="@+id/dialogFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:id="@+id/titleFrame"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:textSize="20sp"
android:textStyle="bold"
android:drawableStart="@drawable/ic_filter"
android:drawablePadding="16dp"
android:text="@string/exploreFilterDialogTitle"
android:layout_marginBottom="4dp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:id="@+id/dividerTitle"
android:background="?attr/dividerColor" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="100"
android:layout_margin="12dp"
android:orientation="vertical">
<CheckBox
android:id="@+id/includeTopic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:textColor="?attr/primaryTextColor"
android:text="@string/exploreFilterIncludeTopic"
android:textSize="16sp" />
<CheckBox
android:id="@+id/includeDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:textColor="?attr/primaryTextColor"
android:text="@string/exploreFilterIncludeDesc"
android:textSize="16sp" />
<CheckBox
android:id="@+id/includeTemplate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:textColor="?attr/primaryTextColor"
android:text="@string/exploreFilterIncludeTemplateRepos"
android:textSize="16sp" />
<CheckBox
android:id="@+id/onlyArchived"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:textColor="?attr/primaryTextColor"
android:text="@string/exploreFilterIncludeArchive"
android:textSize="16sp" />
<CheckBox
android:id="@+id/onlyPrivate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:textColor="?attr/primaryTextColor"
android:text="@string/exploreFilterIncludePrivate"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:id="@+id/divider"
android:background="?attr/dividerColor" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="horizontal" >
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="60dp"
style="?android:attr/button"
android:layout_alignParentStart="true"
android:text="@string/close"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
</RelativeLayout>
</LinearLayout>

View File

@ -13,24 +13,44 @@
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
app:indicatorColor="?attr/progressIndicatorColor" />
<EditText
android:id="@+id/searchKeyword"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="14sp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:inputType="text"
android:background="@drawable/shape_inputs"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:hint="@string/exploreTextBoxHint"
android:textColorHighlight="?attr/primaryTextColor"
android:imeOptions="actionSend"
android:autofillHints="@string/exploreTextBoxHint" />
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/searchKeywordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxBackgroundColor="?attr/inputBackgroundColor"
android:textColorHint="?attr/hintColor"
app:hintTextColor="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:startIconDrawable="@drawable/ic_search"
app:startIconTint="?attr/iconsColor"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
android:hint="@string/exploreTextBoxHint">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/searchKeyword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:imeOptions="actionSend"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<TextView
android:id="@+id/noData"

View File

@ -46,7 +46,7 @@
android:gravity="end"
android:paddingEnd="25dp"
android:paddingStart="15dp"
android:paddingTop="10dp"
android:paddingTop="6dp"
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:id="@+id/userAccountAvatar"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_width="36dp"
android:layout_height="36dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:contentDescription="@string/generalImgContentText"
xmlns:android="http://schemas.android.com/apk/res/android" />

View File

@ -695,6 +695,13 @@
<string name="repoTransferOwnerError">New owner is required</string>
<string name="repoTransferError">There is a problem with the owner name. Make sure that the new owner exists</string>
<string name="exploreFilterDialogTitle">Filter Repositories</string>
<string name="exploreFilterIncludeTopic">Search ONLY in Topic</string>
<string name="exploreFilterIncludeDesc">Search in Description</string>
<string name="exploreFilterIncludeArchive">Only Archived Repositories</string>
<string name="exploreFilterIncludePrivate">Only Private Repositories</string>
<string name="exploreFilterIncludeTemplateRepos">Search in Template Repositories</string>
<string name="mergeIntoBranch">Merge Into</string>
<string name="pullFromBranch">Pull From</string>
<string name="sameBranchesError">These branches are equal. There is no need to create a pull request</string>

View File

@ -210,7 +210,7 @@
</style>
<style name="AppThemeCheckBoxStyle" parent="Base.Widget.AppCompat.CompoundButton.CheckBox">
<item name="buttonTint">@color/colorWhite</item>
<item name="buttonTint">?attr/iconsColor</item>
</style>
<!-- Retro theme styles -->