1
0
mirror of https://codeberg.org/gitnex/GitNex synced 2025-03-12 09:30:05 +01:00

Add attachments to comment (#1384)

Closes #1340

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1384
Co-authored-by: M M Arif <mmarif@swatian.com>
Co-committed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
M M Arif 2024-09-21 18:44:13 +00:00 committed by M M Arif
parent e684e6f40f
commit 8fd3bc9d90
23 changed files with 880 additions and 506 deletions

View File

@ -79,7 +79,7 @@ Thanks to all the open source libraries, contributors, and donors.
- [square/retrofit](https://github.com/square/retrofit)
- [google/gson](https://github.com/google/gson)
- [square/okhttp](https://github.com/square/okhttp)
- [square/picasso](https://github.com/square/picasso)
- [bumptech/glide](https://github.com/bumptech/glide)
- [noties/Markwon](https://github.com/noties/Markwon)
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
- [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable)

View File

@ -309,6 +309,7 @@ public class CreateIssueActivity extends BaseActivity
bottomSheetDialog.setContentView(bottomSheetAttachmentsBinding.getRoot());
bottomSheetDialog.show();
} else {
attachmentsAdapter.clearAdapter();
openFileAttachmentActivity();
}
}

View File

@ -9,6 +9,7 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@ -41,9 +42,11 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
@ -55,9 +58,13 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import org.apache.commons.io.FilenameUtils;
import org.gitnex.tea4j.v2.models.Attachment;
import org.gitnex.tea4j.v2.models.Comment;
import org.gitnex.tea4j.v2.models.CreateIssueCommentOption;
import org.gitnex.tea4j.v2.models.EditIssueOption;
import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.IssueLabelsOption;
@ -72,17 +79,19 @@ import org.mian.gitnex.actions.AssigneesActions;
import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AssigneesListAdapter;
import org.mian.gitnex.adapters.AttachmentsAdapter;
import org.mian.gitnex.adapters.IssueCommentsAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityIssueDetailBinding;
import org.mian.gitnex.databinding.BottomSheetAttachmentsBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomImageViewDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomPrInfoDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
@ -91,9 +100,12 @@ import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.attachments.AttachmentUtils;
import org.mian.gitnex.helpers.attachments.AttachmentsModel;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.notifications.Notifications;
import org.mian.gitnex.structs.BottomSheetListener;
@ -109,7 +121,8 @@ import retrofit2.Response;
public class IssueDetailActivity extends BaseActivity
implements LabelsListAdapter.LabelsListAdapterListener,
AssigneesListAdapter.AssigneesListAdapterListener,
BottomSheetListener {
BottomSheetListener,
AttachmentsAdapter.AttachmentsReceiverListener {
private Typeface myTypeface;
public static boolean singleIssueUpdate = false;
@ -144,12 +157,34 @@ public class IssueDetailActivity extends BaseActivity
private int page = 1;
private TinyDB tinyDB;
private Mode mode = Mode.SEND;
private static List<AttachmentsModel> attachmentsList;
private AttachmentsAdapter attachmentsAdapter;
private static final List<Uri> contentUri = new ArrayList<>();
private InputMethodManager imm;
private float buttonAlphaStatDisabled = .5F;
private float buttonAlphaStatEnabled = 1F;
private enum Mode {
EDIT,
SEND
}
ActivityResultLauncher<Intent> startActivityForResult =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
assert data != null;
contentUri.add(data.getData());
attachmentsList.add(
new AttachmentsModel(
AttachmentUtils.queryName(ctx, data.getData()),
data.getData()));
attachmentsAdapter.updateList(attachmentsList);
}
});
public ActivityResultLauncher<Intent> editIssueLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
@ -299,8 +334,7 @@ public class IssueDetailActivity extends BaseActivity
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
InputMethodManager imm =
(InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
String instanceUrl = ((BaseActivity) ctx).getAccount().getAccount().getInstanceUrl();
instanceUrlOnly = instanceUrl.substring(0, instanceUrl.lastIndexOf("api/v1/"));
@ -316,19 +350,15 @@ public class IssueDetailActivity extends BaseActivity
viewBinding.recyclerView.setNestedScrollingEnabled(false);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
float buttonAlphaStatDisabled = .5F;
float buttonAlphaStatEnabled = 1F;
attachmentsList = new ArrayList<>();
attachmentsAdapter = new AttachmentsAdapter(attachmentsList, ctx);
AttachmentsAdapter.setAttachmentsReceiveListener(this);
viewBinding.send.setAlpha(buttonAlphaStatDisabled);
viewBinding.send.setEnabled(false);
viewBinding.addNewComment.setOnClickListener(
v -> {
BottomSheetReplyFragment bottomSheetReplyFragment =
BottomSheetReplyFragment.newInstance(new Bundle(), issue);
bottomSheetReplyFragment.setOnInteractedListener(this::onResume);
bottomSheetReplyFragment.show(getSupportFragmentManager(), "replyBottomSheet");
});
viewBinding.addAttachments.setOnClickListener(addAttachments -> checkForAttachments());
labelsAdapter =
new LabelsListAdapter(labelsList, IssueDetailActivity.this, currentLabelsIds);
@ -442,43 +472,10 @@ public class IssueDetailActivity extends BaseActivity
mode = Mode.SEND;
}
Log.e("replyCommentId", String.valueOf(tinyDB.getInt("commentId")));
if (mode == Mode.SEND) {
IssueActions.reply(
ctx, viewBinding.commentReply.getText().toString(), issue)
.accept(
(status, result) -> {
if (status == ActionResult.Status.SUCCESS) {
viewBinding.scrollViewComments.post(
() ->
issueCommentsModel
.loadIssueComments(
repoOwner,
repoName,
issueIndex,
ctx,
() ->
viewBinding
.scrollViewComments
.fullScroll(
ScrollView
.FOCUS_DOWN)));
Toasty.success(
ctx, getString(R.string.commentSuccess));
viewBinding.send.setAlpha(buttonAlphaStatDisabled);
viewBinding.send.setEnabled(false);
viewBinding.commentReply.setText(null);
viewBinding.commentReply.clearFocus();
imm.toggleSoftInput(
InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
} else {
Toasty.error(ctx, getString(R.string.genericError));
}
});
createIssueComment(viewBinding.commentReply.getText().toString());
} else {
IssueActions.edit(
@ -490,6 +487,13 @@ public class IssueDetailActivity extends BaseActivity
(status, result) -> {
if (status == ActionResult.Status.SUCCESS) {
if (!contentUri.isEmpty()) {
processAttachments(tinyDB.getInt("commentId"));
contentUri.clear();
AttachmentsAdapter
.setAttachmentsReceiveListener(null);
}
tinyDB.remove("commentId");
tinyDB.remove("commentAction");
@ -523,6 +527,103 @@ public class IssueDetailActivity extends BaseActivity
});
}
public void onDestroy() {
AttachmentsAdapter.setAttachmentsReceiveListener(null);
super.onDestroy();
}
@Override
public void setAttachmentsData(Uri filename) {
contentUri.remove(filename);
}
private void checkForAttachments() {
if (!contentUri.isEmpty()) {
BottomSheetAttachmentsBinding bottomSheetAttachmentsBinding =
BottomSheetAttachmentsBinding.inflate(getLayoutInflater());
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ctx);
bottomSheetAttachmentsBinding.addAttachment.setOnClickListener(
v1 -> openFileAttachmentActivity());
bottomSheetAttachmentsBinding.recyclerViewAttachments.setHasFixedSize(true);
bottomSheetAttachmentsBinding.recyclerViewAttachments.setLayoutManager(
new LinearLayoutManager(ctx));
bottomSheetAttachmentsBinding.recyclerViewAttachments.setAdapter(attachmentsAdapter);
bottomSheetDialog.setContentView(bottomSheetAttachmentsBinding.getRoot());
bottomSheetDialog.show();
} else {
attachmentsAdapter.clearAdapter();
openFileAttachmentActivity();
}
}
private void openFileAttachmentActivity() {
Intent data = new Intent(Intent.ACTION_GET_CONTENT);
data.addCategory(Intent.CATEGORY_OPENABLE);
data.setType("*/*");
Intent intent = Intent.createChooser(data, "Choose a file");
startActivityForResult.launch(intent);
}
public void processAttachments(long commentId) {
for (int i = 0; i < contentUri.size(); i++) {
File file = AttachmentUtils.getFile(ctx, contentUri.get(i));
RequestBody requestFile =
RequestBody.create(
file,
MediaType.parse(
Objects.requireNonNull(
getContentResolver().getType(contentUri.get(i)))));
uploadAttachments(requestFile, commentId, file.getName());
}
}
private void uploadAttachments(RequestBody requestFile, long commentId, String filename1) {
Call<Attachment> call3;
call3 =
RetrofitClient.getApiInterface(ctx)
.issueCreateIssueCommentAttachment(
requestFile, repoOwner, repoName, commentId, filename1);
call3.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<Attachment> call,
@NonNull retrofit2.Response<Attachment> response2) {
if (response2.code() == 201) {
Log.e("Attachments", "Files uploaded");
}
if (response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx);
}
}
@Override
public void onFailure(@NonNull Call<Attachment> call, @NonNull Throwable t) {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
}
});
}
@Override
public void onButtonClicked(String text) {
@ -786,6 +887,7 @@ public class IssueDetailActivity extends BaseActivity
startActivity(intent);
}
finish();
contentUri.clear();
return true;
} else if (id == R.id.genericMenu) {
@ -870,8 +972,8 @@ public class IssueDetailActivity extends BaseActivity
500);
}
tinyDB.remove("commentId");
tinyDB.remove("commentAction");
// tinyDB.remove("commentId");
// tinyDB.remove("commentAction");
mode = Mode.SEND;
}
@ -1602,4 +1704,83 @@ public class IssueDetailActivity extends BaseActivity
materialAlertDialogBuilder.create().show();
}
private void createIssueComment(String comment) {
CreateIssueCommentOption issueComment = new CreateIssueCommentOption();
issueComment.setBody(comment);
Call<Comment> call =
RetrofitClient.getApiInterface(ctx)
.issueCreateComment(
issue.getRepository().getOwner(),
issue.getRepository().getName(),
(long) issue.getIssueIndex(),
issueComment);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<Comment> call,
@NonNull retrofit2.Response<Comment> response) {
if (response.code() == 201) {
assert response.body() != null;
if (issue.hasIssue()) {
IssuesFragment.resumeIssues =
issue.getIssue().getPullRequest() == null;
PullRequestsFragment.resumePullRequests =
issue.getIssue().getPullRequest() != null;
}
if (!contentUri.isEmpty()) {
processAttachments(response.body().getId());
contentUri.clear();
AttachmentsAdapter.setAttachmentsReceiveListener(null);
}
viewBinding.scrollViewComments.post(
() ->
issueCommentsModel.loadIssueComments(
repoOwner,
repoName,
issueIndex,
ctx,
() ->
viewBinding.scrollViewComments
.fullScroll(
ScrollView
.FOCUS_DOWN)));
Toasty.success(ctx, getString(R.string.commentSuccess));
viewBinding.send.setAlpha(buttonAlphaStatDisabled);
viewBinding.send.setEnabled(false);
viewBinding.commentReply.setText(null);
viewBinding.commentReply.clearFocus();
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
} else if (response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else {
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<Comment> call, @NonNull Throwable t) {
Toasty.error(
ctx,
ctx.getResources().getString(R.string.genericServerResponseError));
}
});
}
}

View File

@ -114,6 +114,11 @@ public class AttachmentsAdapter extends RecyclerView.Adapter<AttachmentsAdapter.
notifyItemRangeChanged(position, attachmentsList.size());
}
public void clearAdapter() {
attachmentsList.clear();
notifyDataChanged();
}
public interface AttachmentsReceiverListener {
void setAttachmentsData(Uri myData);
}

View File

@ -159,4 +159,9 @@ public class MostVisitedReposAdapter
mostVisitedReposList = list;
notifyDataChanged();
}
public void clearAdapter() {
mostVisitedReposList.clear();
notifyDataChanged();
}
}

View File

@ -200,4 +200,9 @@ public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesViewHol
notesList = list;
notifyDataChanged();
}
public void clearAdapter() {
notesList.clear();
notifyDataChanged();
}
}

View File

@ -14,11 +14,15 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.vdurmont.emoji.EmojiParser;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.gitnex.tea4j.v2.models.Organization;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OrganizationDetailActivity;
import org.mian.gitnex.helpers.Markdown;
/**
* @author M M Arif
@ -179,7 +183,12 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<RecyclerView.
if (!org.getDescription().isEmpty()) {
orgDescription.setVisibility(View.VISIBLE);
orgDescription.setText(org.getDescription());
Markdown.render(
context,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
StringUtils.substring(org.getDescription(), 0, 280))),
orgDescription);
} else {
orgDescription.setVisibility(View.GONE);
}

View File

@ -11,7 +11,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -34,9 +36,54 @@ public class ExploreIssuesFragment extends Fragment {
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewBinding = FragmentSearchIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
issuesViewModel = new ViewModelProvider(this).get(IssuesViewModel.class);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menu.clear();
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
fetchDataAsync(query);
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
viewBinding.pullToRefresh.setOnRefreshListener(
() ->
new Handler(Looper.getMainLooper())
@ -103,35 +150,4 @@ public class ExploreIssuesFragment extends Fragment {
viewBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.search_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) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
fetchDataAsync(query);
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
}

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
@ -60,7 +62,6 @@ public class ExploreRepositoriesFragment extends Fragment {
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewBinding = FragmentExploreRepoBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
context = getContext();
dataList = new ArrayList<>();
@ -68,6 +69,81 @@ public class ExploreRepositoriesFragment extends Fragment {
resultLimit = Constants.getCurrentResultLimit(context);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menu.clear();
menuInflater.inflate(R.menu.search_menu, menu);
menuInflater.inflate(R.menu.filter_menu_explore, menu);
MenuItem filter = menu.findItem(R.id.filter_explore);
filter.setOnMenuItemClickListener(
filter_ -> {
showFilterOptions();
return false;
});
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
loadInitial(query, resultLimit);
adapter.setLoadMoreListener(
() ->
viewBinding.recyclerViewReposSearch
.post(
() -> {
if (dataList
.size()
== resultLimit
|| pageSize
== resultLimit) {
int page =
(dataList
.size()
+ resultLimit)
/ resultLimit;
loadMore(
query,
resultLimit,
page);
}
}));
searchQuery = query;
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
viewBinding.pullToRefresh.setOnRefreshListener(
() ->
new Handler(Looper.getMainLooper())
@ -127,7 +203,7 @@ public class ExploreRepositoriesFragment extends Fragment {
@NonNull Call<SearchResults> call,
@NonNull Response<SearchResults> response) {
if (response.isSuccessful()) {
if (response.body() != null && response.body().getData().size() > 0) {
if (response.body() != null && !response.body().getData().isEmpty()) {
dataList.clear();
dataList.addAll(response.body().getData());
adapter.notifyDataChanged();
@ -195,7 +271,7 @@ public class ExploreRepositoriesFragment extends Fragment {
if (response.isSuccessful()) {
assert response.body() != null;
List<Repository> result = response.body().getData();
if (result.size() > 0) {
if (!result.isEmpty()) {
pageSize = result.size();
dataList.addAll(result);
} else {
@ -228,58 +304,6 @@ public class ExploreRepositoriesFragment extends Fragment {
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.search_menu, menu);
inflater.inflate(R.menu.filter_menu_explore, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem filter = menu.findItem(R.id.filter_explore);
filter.setOnMenuItemClickListener(
filter_ -> {
showFilterOptions();
return false;
});
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) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
loadInitial(query, resultLimit);
adapter.setLoadMoreListener(
() ->
viewBinding.recyclerViewReposSearch.post(
() -> {
if (dataList.size() == resultLimit
|| pageSize == resultLimit) {
int page =
(dataList.size() + resultLimit)
/ resultLimit;
loadMore(query, resultLimit, page);
}
}));
searchQuery = query;
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
private void showFilterOptions() {
MaterialAlertDialogBuilder materialAlertDialogBuilder =

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.util.ArrayList;
import java.util.List;
@ -48,13 +50,78 @@ public class ExploreUsersFragment extends Fragment {
viewBinding = FragmentExploreUsersBinding.inflate(inflater, container, false);
context = getContext();
setHasOptionsMenu(true);
resultLimit = Constants.getCurrentResultLimit(context);
usersList = new ArrayList<>();
adapter = new UsersAdapter(usersList, context);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menu.clear();
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
loadInitial(query, resultLimit);
adapter.setLoadMoreListener(
() ->
viewBinding.recyclerViewExploreUsers
.post(
() -> {
if (usersList
.size()
== resultLimit
|| pageSize
== resultLimit) {
int page =
(usersList
.size()
+ resultLimit)
/ resultLimit;
loadMore(
query,
resultLimit,
page);
}
}));
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
viewBinding.pullToRefresh.setOnRefreshListener(
() ->
new Handler(Looper.getMainLooper())
@ -99,7 +166,7 @@ public class ExploreUsersFragment extends Fragment {
@NonNull Call<InlineResponse2001> call,
@NonNull Response<InlineResponse2001> response) {
if (response.isSuccessful()) {
if (response.body() != null && response.body().getData().size() > 0) {
if (response.body() != null && !response.body().getData().isEmpty()) {
usersList.clear();
usersList.addAll(response.body().getData());
adapter.notifyDataChanged();
@ -152,7 +219,7 @@ public class ExploreUsersFragment extends Fragment {
assert response.body() != null;
List<User> result = response.body().getData();
if (result != null) {
if (result.size() > 0) {
if (!result.isEmpty()) {
pageSize = result.size();
usersList.addAll(result);
} else {
@ -186,47 +253,4 @@ public class ExploreUsersFragment extends Fragment {
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.search_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) {
viewBinding.progressBar.setVisibility(View.VISIBLE);
loadInitial(query, resultLimit);
adapter.setLoadMoreListener(
() ->
viewBinding.recyclerViewExploreUsers.post(
() -> {
if (usersList.size() == resultLimit
|| pageSize == resultLimit) {
int page =
(usersList.size() + resultLimit)
/ resultLimit;
loadMore(query, resultLimit, page);
}
}));
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
}

View File

@ -13,7 +13,9 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
@ -48,7 +50,6 @@ public class MostVisitedReposFragment extends Fragment {
fragmentDraftsBinding = FragmentDraftsBinding.inflate(inflater, container, false);
ctx = getContext();
setHasOptionsMenu(true);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navMostVisited));
@ -75,6 +76,69 @@ public class MostVisitedReposFragment extends Fragment {
fetchDataAsync(currentActiveAccountId);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.reset_menu, menu);
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
Objects.requireNonNull(searchView)
.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.reset_menu_item) {
if (mostVisitedReposList.isEmpty()) {
Toasty.warning(
ctx,
getResources().getString(R.string.noDataFound));
} else {
new MaterialAlertDialogBuilder(ctx)
.setTitle(R.string.reset)
.setMessage(R.string.resetCounterAllDialogMessage)
.setPositiveButton(
R.string.reset,
(dialog, which) -> {
resetAllRepositoryCounter(
currentActiveAccountId);
dialog.dismiss();
})
.setNeutralButton(R.string.cancelButton, null)
.show();
}
}
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
return fragmentDraftsBinding.getRoot();
}
@ -87,7 +151,7 @@ public class MostVisitedReposFragment extends Fragment {
mostVisitedRepos -> {
fragmentDraftsBinding.pullToRefresh.setRefreshing(false);
assert mostVisitedRepos != null;
if (mostVisitedRepos.size() > 0) {
if (!mostVisitedRepos.isEmpty()) {
mostVisitedReposList.clear();
fragmentDraftsBinding.noData.setVisibility(View.GONE);
@ -103,72 +167,18 @@ public class MostVisitedReposFragment extends Fragment {
public void resetAllRepositoryCounter(int accountId) {
if (mostVisitedReposList.size() > 0) {
if (!mostVisitedReposList.isEmpty()) {
Objects.requireNonNull(BaseApi.getInstance(ctx, RepositoriesApi.class))
.resetAllRepositoryMostVisited(accountId);
mostVisitedReposList.clear();
adapter.notifyDataChanged();
adapter.clearAdapter();
Toasty.success(ctx, getResources().getString(R.string.resetMostReposCounter));
} else {
Toasty.warning(ctx, getResources().getString(R.string.noDataFound));
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.reset_menu, menu);
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
Objects.requireNonNull(searchView).setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.reset_menu_item) {
if (mostVisitedReposList.size() == 0) {
Toasty.warning(ctx, getResources().getString(R.string.noDataFound));
} else {
new MaterialAlertDialogBuilder(ctx)
.setTitle(R.string.reset)
.setMessage(R.string.resetCounterAllDialogMessage)
.setPositiveButton(
R.string.reset,
(dialog, which) -> {
resetAllRepositoryCounter(currentActiveAccountId);
dialog.dismiss();
})
.setNeutralButton(R.string.cancelButton, null)
.show();
}
}
return super.onOptionsItemSelected(item);
}
private void filter(String text) {
List<Repository> arr = new ArrayList<>();

View File

@ -11,7 +11,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -38,7 +40,52 @@ public class MyIssuesFragment extends Fragment {
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu1, @NonNull MenuInflater menuInflater) {
menu = menu1;
menuInflater.inflate(R.menu.search_menu, menu1);
menuInflater.inflate(R.menu.filter_menu, menu1);
MenuItem searchItem = menu1.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
fetchDataAsync(query, state, assignedToMe);
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
issuesViewModel = new ViewModelProvider(this).get(IssuesViewModel.class);
fragmentIssuesBinding.recyclerView.setHasFixedSize(true);
@ -137,36 +184,4 @@ 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();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
fetchDataAsync(query, state, assignedToMe);
searchView.setQuery(null, false);
searchItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
}

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -41,7 +43,51 @@ public class MyRepositoriesFragment extends Fragment {
fragmentRepositoriesBinding =
FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView
.getAdapter()
!= null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navMyRepos));
repositoriesViewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
@ -150,33 +196,4 @@ public class MyRepositoriesFragment extends Fragment {
MainActivity.reloadRepos = false;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_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) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -14,7 +14,9 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
@ -48,7 +50,68 @@ public class NotesFragment extends Fragment {
binding = FragmentNotesBinding.inflate(inflater, container, false);
ctx = getContext();
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.reset_menu, menu);
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.reset_menu_item) {
if (notesList.isEmpty()) {
Toasty.warning(
ctx,
getResources().getString(R.string.noDataFound));
} else {
new MaterialAlertDialogBuilder(ctx)
.setTitle(R.string.menuDeleteText)
.setMessage(R.string.notesAllDeletionMessage)
.setPositiveButton(
R.string.menuDeleteText,
(dialog, which) -> {
deleteAllNotes();
dialog.dismiss();
})
.setNeutralButton(R.string.cancelButton, null)
.show();
}
}
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navNotes));
@ -142,66 +205,11 @@ public class NotesFragment extends Fragment {
notesApi.deleteAllNotes();
notesList.clear();
adapter.notifyDataChanged();
adapter.clearAdapter();
Toasty.success(
ctx, ctx.getResources().getQuantityString(R.plurals.noteDeleteMessage, 2));
} else {
Toasty.warning(ctx, getResources().getString(R.string.noDataFound));
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.reset_menu, menu);
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.reset_menu_item) {
if (notesList.isEmpty()) {
Toasty.warning(ctx, getResources().getString(R.string.noDataFound));
} else {
new MaterialAlertDialogBuilder(ctx)
.setTitle(R.string.menuDeleteText)
.setMessage(R.string.notesAllDeletionMessage)
.setPositiveButton(
R.string.menuDeleteText,
(dialog, which) -> {
deleteAllNotes();
dialog.dismiss();
})
.setNeutralButton(R.string.cancelButton, null)
.show();
}
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -42,7 +44,50 @@ public class OrganizationsFragment extends Fragment {
fragmentOrganizationsBinding =
FragmentOrganizationsBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentOrganizationsBinding.recyclerView
.getAdapter()
!= null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navOrg));
organizationsViewModel = new ViewModelProvider(this).get(OrganizationsViewModel.class);
@ -132,33 +177,4 @@ public class OrganizationsFragment extends Fragment {
orgCreated = false;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_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) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentOrganizationsBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -40,7 +42,51 @@ public class RepositoriesFragment extends Fragment {
fragmentRepositoriesBinding =
FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView
.getAdapter()
!= null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navRepos));
repositoriesViewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
@ -141,33 +187,4 @@ public class RepositoriesFragment extends Fragment {
MainActivity.reloadRepos = false;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_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) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -40,7 +42,51 @@ public class StarredRepositoriesFragment extends Fragment {
fragmentRepositoriesBinding =
FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView
.getAdapter()
!= null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navStarredRepos));
repositoriesViewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
@ -134,35 +180,6 @@ public class StarredRepositoriesFragment extends Fragment {
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_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) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public void onResume() {
super.onResume();

View File

@ -12,7 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R;
@ -40,7 +42,51 @@ public class WatchedRepositoriesFragment extends Fragment {
fragmentRepositoriesBinding =
FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
requireActivity()
.addMenuProvider(
new MenuProvider() {
@Override
public void onCreateMenu(
@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView =
(androidx.appcompat.widget.SearchView)
searchItem.getActionView();
assert searchView != null;
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView
.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView
.getAdapter()
!= null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
},
getViewLifecycleOwner(),
Lifecycle.State.RESUMED);
((MainActivity) requireActivity())
.setActionBarTitle(getResources().getString(R.string.navWatchedRepositories));
repositoriesViewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
@ -134,35 +180,6 @@ public class WatchedRepositoriesFragment extends Fragment {
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_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) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
@Override
public void onResume() {
super.onResume();

View File

@ -2,6 +2,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/primaryBackgroundColor"/>
<corners android:radius="32dp"/>
<corners android:radius="12dp"/>
</shape>

View File

@ -8,7 +8,7 @@
</solid>
<corners
android:radius="32dp">
android:radius="12dp">
</corners>
<padding

View File

@ -52,20 +52,6 @@
android:indeterminate="true"
app:indicatorColor="?attr/progressIndicatorColor" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/addNewComment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/dimen16dp"
android:backgroundTint="?attr/fabColor"
android:contentDescription="@string/commentButtonText"
android:text="@string/commentButtonText"
android:textColor="?attr/materialCardBackgroundColor"
app:iconTint="?attr/materialCardBackgroundColor"
android:visibility="gone"
app:icon="@drawable/ic_reply" />
<RelativeLayout
android:id="@+id/relativeMainLayoutFrame"
android:layout_width="match_parent"
@ -151,9 +137,9 @@
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
app:cardCornerRadius="@dimen/dimen12dp"
android:layout_width="@dimen/dimen32dp"
android:layout_height="@dimen/dimen32dp"
app:cardCornerRadius="@dimen/dimen8dp"
app:cardElevation="@dimen/dimen0dp"
tools:ignore="TooDeepLayout">
@ -399,10 +385,10 @@
android:layout_gravity="center_vertical"
android:backgroundTint="?attr/fabColor"
android:layout_marginEnd="@dimen/dimen8dp"
app:cardCornerRadius="@dimen/dimen36dp">
app:cardCornerRadius="@dimen/dimen12dp">
<ImageView
android:id="@+id/attachments"
android:id="@+id/add_attachments"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
android:layout_gravity="center_vertical|center_horizontal"
@ -439,7 +425,7 @@
android:layout_height="@dimen/dimen38dp"
android:layout_gravity="center_vertical"
android:backgroundTint="?attr/fabColor"
app:cardCornerRadius="@dimen/dimen36dp">
app:cardCornerRadius="@dimen/dimen12dp">
<ImageView
android:id="@+id/send"

View File

@ -205,7 +205,7 @@
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/repoWatchersInMenu"
android:contentDescription="@string/infoTabRepoSize"
app:srcCompat="@drawable/ic_download"/>
<LinearLayout

View File

@ -7,6 +7,7 @@
app:cardCornerRadius="@dimen/dimen8dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="@dimen/dimen4dp"
android:backgroundTint="@android:color/transparent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">