diff --git a/README.md b/README.md
index e7f76f8d..a71f4ef4 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ GitNex is a free/paid, open-source Android client for Git repository management
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. **No trackers are used** and source code is available here for anyone to audit.
## Downloads
-[
](https://f-droid.org/en/packages/org.mian.gitnex/)
+[
](https://f-droid.org/en/packages/org.mian.gitnex/)
[
](https://play.google.com/store/apps/details?id=org.mian.gitnex.pro)
[
](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE)
diff --git a/app/build.gradle b/app/build.gradle
index 3738d3cb..86c3f050 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -56,7 +56,7 @@ configurations {
dependencies {
def lifecycle_version = '2.3.1'
def markwon_version = '4.6.2'
- def work_version = "2.5.0"
+ def work_version = "2.7.0-alpha03"
def acra = "5.7.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
@@ -103,12 +103,12 @@ dependencies {
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
- implementation 'androidx.room:room-runtime:2.2.6'
- annotationProcessor 'androidx.room:room-compiler:2.2.6'
+ implementation 'androidx.room:room-runtime:2.3.0'
+ annotationProcessor 'androidx.room:room-compiler:2.3.0'
implementation "androidx.work:work-runtime:$work_version"
implementation "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
- implementation "org.codeberg.gitnex:tea4j:1.0.5"
+ implementation "org.codeberg.gitnex:tea4j:1.0.10"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.github.chrisvest:stormpot:2.4.1'
diff --git a/app/src/main/java/org/mian/gitnex/adapters/PublicOrganizationsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/PublicOrganizationsAdapter.java
new file mode 100644
index 00000000..5a8e7528
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/PublicOrganizationsAdapter.java
@@ -0,0 +1,148 @@
+package org.mian.gitnex.adapters;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import org.gitnex.tea4j.models.Organization;
+import org.mian.gitnex.R;
+import org.mian.gitnex.activities.OrganizationDetailActivity;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import org.mian.gitnex.helpers.TinyDB;
+import java.util.List;
+
+/**
+ * Author M M Arif
+ */
+
+public class PublicOrganizationsAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List organizationsList;
+ private OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public PublicOrganizationsAdapter(Context ctx, List organizationsListMain) {
+ this.context = ctx;
+ this.organizationsList = organizationsListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ LayoutInflater inflater = LayoutInflater.from(context);
+ if(viewType == TYPE_LOAD) {
+ return new PublicOrganizationsAdapter.OrganizationsHolder(inflater.inflate(R.layout.list_organizations, parent, false));
+ }
+ else {
+ return new PublicOrganizationsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+ if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
+ isLoading = true;
+ loadMoreListener.onLoadMore();
+ }
+
+ if(getItemViewType(position) == TYPE_LOAD) {
+ ((PublicOrganizationsAdapter.OrganizationsHolder) holder).bindData(organizationsList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(organizationsList.get(position).getFull_name() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return organizationsList.size();
+ }
+
+ class OrganizationsHolder extends RecyclerView.ViewHolder {
+ private Organization organization;
+ private final ImageView image;
+ private final TextView orgName;
+ private final TextView orgDescription;
+
+ OrganizationsHolder(View itemView) {
+ super(itemView);
+ image = itemView.findViewById(R.id.imageAvatar);
+ orgName = itemView.findViewById(R.id.orgName);
+ orgDescription = itemView.findViewById(R.id.orgDescription);
+
+ itemView.setOnClickListener(v -> {
+ Context context = v.getContext();
+ Intent intent = new Intent(context, OrganizationDetailActivity.class);
+ intent.putExtra("orgName", organization.getUsername());
+
+ TinyDB tinyDb = TinyDB.getInstance(context);
+ tinyDb.putString("orgName", organization.getUsername());
+ tinyDb.putString("organizationId", String.valueOf(organization.getId()));
+ tinyDb.putBoolean("organizationAction", true);
+ context.startActivity(intent);
+ });
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(Organization organization) {
+ this.organization = organization;
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+ orgName.setText(organization.getUsername());
+ PicassoService.getInstance(context).get()
+ .load(organization.getAvatar_url())
+ .placeholder(R.drawable.loader_animated)
+ .transform(new RoundedTransformation(imgRadius, 0))
+ .resize(120, 120)
+ .centerCrop()
+ .into(image);
+ if (!organization.getDescription().equals("")) {
+ orgDescription.setText(organization.getDescription());
+ }
+ }
+ }
+
+ static class LoadHolder extends RecyclerView.ViewHolder {
+ LoadHolder(View itemView) {
+ super(itemView);
+ }
+ }
+
+ public void setMoreDataAvailable(boolean moreDataAvailable) {
+ isMoreDataAvailable = moreDataAvailable;
+ }
+
+ public void notifyDataChanged() {
+ notifyDataSetChanged();
+ isLoading = false;
+ }
+
+ public interface OnLoadMoreListener {
+ void onLoadMore();
+ }
+
+ public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
+ this.loadMoreListener = loadMoreListener;
+ }
+
+ public void updateList(List list) {
+ organizationsList = list;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java
index 58544f8f..5ea4b5cf 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java
@@ -24,9 +24,6 @@ import org.mian.gitnex.helpers.TinyDB;
public class ExploreFragment extends Fragment {
- private Context ctx;
- private TinyDB tinyDB;
-
private int tabsCount;
public ViewPager mViewPager;
@@ -36,8 +33,8 @@ public class ExploreFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_explore, container, false);
- ctx = getContext();
- tinyDB = TinyDB.getInstance(ctx);
+ Context ctx = getContext();
+ TinyDB tinyDB = TinyDB.getInstance(ctx);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navExplore));
@@ -111,7 +108,11 @@ public class ExploreFragment extends Fragment {
break;
case 1: // Issues
- fragment = new SearchIssuesFragment();
+ fragment = new ExploreIssuesFragment();
+ break;
+
+ case 2: // Organizations
+ fragment = new ExplorePublicOrganizationsFragment();
break;
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExploreIssuesFragment.java
similarity index 94%
rename from app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/ExploreIssuesFragment.java
index 374dc47c..180a8a90 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/ExploreIssuesFragment.java
@@ -19,7 +19,6 @@ import org.mian.gitnex.databinding.FragmentSearchIssuesBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.InfiniteScrollListener;
-import org.mian.gitnex.helpers.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -31,27 +30,22 @@ import retrofit2.Response;
* Author M M Arif
*/
-public class SearchIssuesFragment extends Fragment {
+public class ExploreIssuesFragment extends Fragment {
- private Context ctx;
- private TinyDB tinyDb;
private FragmentSearchIssuesBinding viewBinding;
private SearchIssuesAdapter adapter;
private List dataList;
+ Context ctx;
private int apiCallCurrentValue = 10;
private int pageCurrentIndex = 1;
- private String type = "issues";
- private String state = "open";
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewBinding = FragmentSearchIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
-
ctx = getContext();
- tinyDb = TinyDB.getInstance(getContext());
dataList = new ArrayList<>();
adapter = new SearchIssuesAdapter(dataList, ctx);
@@ -65,11 +59,8 @@ public class SearchIssuesFragment extends Fragment {
viewBinding.recyclerViewSearchIssues.setAdapter(adapter);
viewBinding.searchKeyword.setOnEditorActionListener((v1, actionId, event) -> {
-
if(actionId == EditorInfo.IME_ACTION_SEND) {
-
if(!Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString().equals("")) {
-
InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(viewBinding.searchKeyword.getWindowToken(), 0);
@@ -79,27 +70,21 @@ public class SearchIssuesFragment extends Fragment {
loadData(false, viewBinding.searchKeyword.getText().toString());
}
}
-
return false;
});
viewBinding.recyclerViewSearchIssues.addOnScrollListener(new InfiniteScrollListener(pageCurrentIndex, linearLayoutManager) {
-
@Override
public void onScrolledToEnd(int firstVisibleItemPosition) {
-
pageCurrentIndex++;
loadData(true, Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString());
-
}
});
viewBinding.pullToRefresh.setOnRefreshListener(() -> {
-
pageCurrentIndex = 1;
apiCallCurrentValue = 10;
loadData(false, Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString());
-
});
loadData(false, "");
@@ -117,69 +102,50 @@ public class SearchIssuesFragment extends Fragment {
}
if(pageCurrentIndex == 1 || !append) {
-
dataList.clear();
adapter.notifyDataSetChanged();
viewBinding.pullToRefresh.setRefreshing(false);
viewBinding.progressBar.setVisibility(View.VISIBLE);
}
else {
-
viewBinding.loadingMoreView.setVisibility(View.VISIBLE);
}
Call> call = RetrofitClient.getApiInterface(getContext())
- .queryIssues(Authorization.get(getContext()), searchKeyword, type, state, pageCurrentIndex);
+ .queryIssues(Authorization.get(getContext()), searchKeyword, "issues", "open", pageCurrentIndex);
call.enqueue(new Callback>() {
-
@Override
public void onResponse(@NonNull Call> call, @NonNull Response> response) {
-
if(response.code() == 200) {
-
assert response.body() != null;
apiCallCurrentValue = response.body().size();
-
if(!append) {
-
dataList.clear();
}
-
dataList.addAll(response.body());
adapter.notifyDataSetChanged();
-
}
else {
-
dataList.clear();
adapter.notifyDataChanged();
viewBinding.noData.setVisibility(View.VISIBLE);
-
}
-
onCleanup();
-
}
@Override
public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
-
Log.e("onFailure", Objects.requireNonNull(t.getMessage()));
onCleanup();
-
}
private void onCleanup() {
-
AppUtil.setMultiVisibility(View.GONE, viewBinding.loadingMoreView, viewBinding.progressBar);
-
if(dataList.isEmpty()) {
-
viewBinding.noData.setVisibility(View.VISIBLE);
}
}
});
}
-
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ExplorePublicOrganizationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExplorePublicOrganizationsFragment.java
new file mode 100644
index 00000000..d49de8b1
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/ExplorePublicOrganizationsFragment.java
@@ -0,0 +1,160 @@
+package org.mian.gitnex.fragments;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.Organization;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.PublicOrganizationsAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentOrganizationsBinding;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class ExplorePublicOrganizationsFragment extends Fragment {
+
+ private FragmentOrganizationsBinding fragmentPublicOrgBinding;
+ private List organizationsList;
+ private PublicOrganizationsAdapter adapter;
+ private Context context;
+ private int pageSize;
+ private final String TAG = Constants.publicOrganizations;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentPublicOrgBinding = FragmentOrganizationsBinding.inflate(inflater, container, false);
+ context = getContext();
+
+ TinyDB tinyDb = TinyDB.getInstance(getContext());
+ final String loginUid = tinyDb.getString("loginUid");
+ final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ fragmentPublicOrgBinding.addNewOrganization.setVisibility(View.GONE);
+ organizationsList = new ArrayList<>();
+
+ fragmentPublicOrgBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentPublicOrgBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(instanceToken, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new PublicOrganizationsAdapter(getContext(), organizationsList);
+ adapter.setLoadMoreListener(() -> fragmentPublicOrgBinding.recyclerView.post(() -> {
+ if(organizationsList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (organizationsList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(getContext()), page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentPublicOrgBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL);
+ fragmentPublicOrgBinding.recyclerView.setHasFixedSize(true);
+ fragmentPublicOrgBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentPublicOrgBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentPublicOrgBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(getContext()), resultLimit);
+
+ return fragmentPublicOrgBinding.getRoot();
+ }
+
+ private void loadInitial(String token, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context).getAllOrgs(token, Constants.publicOrganizationsPageInit, resultLimit);
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+ if(response.isSuccessful()) {
+ if(response.body() != null && response.body().size() > 0) {
+ organizationsList.clear();
+ organizationsList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentPublicOrgBinding.noDataOrg.setVisibility(View.GONE);
+ }
+ else {
+ organizationsList.clear();
+ adapter.notifyDataChanged();
+ fragmentPublicOrgBinding.noDataOrg.setVisibility(View.VISIBLE);
+ }
+ fragmentPublicOrgBinding.progressBar.setVisibility(View.GONE);
+ }
+ else if(response.code() == 404) {
+ fragmentPublicOrgBinding.noDataOrg.setVisibility(View.VISIBLE);
+ fragmentPublicOrgBinding.progressBar.setVisibility(View.GONE);
+ }
+ else {
+ Log.e(TAG, String.valueOf(response.code()));
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Log.e(TAG, t.toString());
+ }
+ });
+ }
+
+ private void loadMore(String token, int page, int resultLimit) {
+
+ fragmentPublicOrgBinding.progressLoadMore.setVisibility(View.VISIBLE);
+ Call> call = RetrofitClient.getApiInterface(context).getAllOrgs(token, page, resultLimit);
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+ if(response.isSuccessful()) {
+ List result = response.body();
+ if(result != null) {
+ if(result.size() > 0) {
+ pageSize = result.size();
+ organizationsList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentPublicOrgBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ }
+ adapter.notifyDataChanged();
+ fragmentPublicOrgBinding.progressLoadMore.setVisibility(View.GONE);
+ }
+ else {
+ Log.e(TAG, String.valueOf(response.code()));
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Log.e(TAG, t.toString());
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
index 88095d88..eda404ac 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
@@ -29,8 +29,8 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentIssuesBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB;
-import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import java.util.ArrayList;
import java.util.List;
@@ -44,6 +44,7 @@ import retrofit2.Response;
public class IssuesFragment extends Fragment {
+ private FragmentIssuesBinding fragmentIssuesBinding;
private Menu menu;
private RecyclerView recyclerView;
private List issuesList;
@@ -51,18 +52,17 @@ public class IssuesFragment extends Fragment {
private Context context;
private int pageSize = Constants.issuesPageInit;
private ProgressBar mProgressBar;
- private String TAG = Constants.tagIssuesList;
+ private final String TAG = Constants.tagIssuesList;
private TextView noDataIssues;
private int resultLimit = Constants.resultLimitOldGiteaInstances;
- private String requestType = Constants.issuesRequestType;
+ private final String requestType = Constants.issuesRequestType;
private ProgressBar progressLoadMore;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- FragmentIssuesBinding fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false);
-
+ fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
context = getContext();
@@ -89,23 +89,17 @@ public class IssuesFragment extends Fragment {
noDataIssues = fragmentIssuesBinding.noDataIssues;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
-
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
adapter.notifyDataChanged();
-
}, 200));
adapter = new IssuesAdapter(getContext(), issuesList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
-
if(issuesList.size() == resultLimit || pageSize == resultLimit) {
-
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
-
}
-
}));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
@@ -129,12 +123,9 @@ public class IssuesFragment extends Fragment {
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(issuesList.size() == resultLimit || pageSize == resultLimit) {
-
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
-
}
-
}));
tinyDb.putString("repoIssuesState", issueState);
@@ -144,13 +135,11 @@ public class IssuesFragment extends Fragment {
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, issueState);
recyclerView.setAdapter(adapter);
-
});
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
return fragmentIssuesBinding.getRoot();
-
}
@Override
@@ -165,11 +154,9 @@ public class IssuesFragment extends Fragment {
final String repoName = parts[1];
if(tinyDb.getBoolean("resumeIssues")) {
-
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
tinyDb.putBoolean("resumeIssues", false);
}
-
}
private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType, String issueState) {
@@ -177,49 +164,38 @@ public class IssuesFragment extends Fragment {
Call> call = RetrofitClient.getApiInterface(context).getIssues(token, repoOwner, repoName, 1, resultLimit, requestType, issueState);
call.enqueue(new Callback>() {
-
@Override
public void onResponse(@NonNull Call> call, @NonNull Response> response) {
if(response.code() == 200) {
-
assert response.body() != null;
if(response.body().size() > 0) {
-
issuesList.clear();
issuesList.addAll(response.body());
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.GONE);
}
else {
-
issuesList.clear();
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.VISIBLE);
}
-
mProgressBar.setVisibility(View.GONE);
-
}
else if(response.code() == 404) {
-
noDataIssues.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
-
}
@Override
public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
-
Log.e(TAG, t.toString());
}
-
});
-
}
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String requestType, String issueState) {
@@ -232,44 +208,29 @@ public class IssuesFragment extends Fragment {
@Override
public void onResponse(@NonNull Call> call, @NonNull Response> response) {
-
if(response.code() == 200) {
-
List result = response.body();
-
assert result != null;
if(result.size() > 0) {
-
pageSize = result.size();
issuesList.addAll(result);
-
}
else {
-
- Toasty.warning(context, getString(R.string.noMoreData));
+ SnackBar.info(context, fragmentIssuesBinding.getRoot(), getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
-
}
-
adapter.notifyDataChanged();
progressLoadMore.setVisibility(View.GONE);
-
}
else {
-
Log.e(TAG, String.valueOf(response.code()));
-
}
-
}
@Override
public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
-
Log.e(TAG, t.toString());
-
}
-
});
}
@@ -298,19 +259,15 @@ public class IssuesFragment extends Fragment {
@Override
public boolean onQueryTextSubmit(String query) {
-
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
-
filter(newText);
return false;
}
-
});
-
}
private void filter(String text) {
@@ -328,5 +285,4 @@ public class IssuesFragment extends Fragment {
adapter.updateList(arr);
}
-
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java
index a62be27d..61a42132 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java
@@ -16,6 +16,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -95,12 +96,15 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
notificationsActions = new NotificationsActions(context);
notificationsAdapter = new NotificationsAdapter(context, notificationThreads, this, this);
+ RecyclerView recyclerView = fragmentNotificationsBinding.notifications;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
- RecyclerView recyclerView = fragmentNotificationsBinding.notifications;
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
+
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(notificationsAdapter);
+ recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.addOnScrollListener(new InfiniteScrollListener(pageResultLimit, linearLayoutManager) {
@Override
diff --git a/app/src/main/java/org/mian/gitnex/helpers/Constants.java b/app/src/main/java/org/mian/gitnex/helpers/Constants.java
index c9683935..3c06b35d 100644
--- a/app/src/main/java/org/mian/gitnex/helpers/Constants.java
+++ b/app/src/main/java/org/mian/gitnex/helpers/Constants.java
@@ -30,6 +30,7 @@ public class Constants {
public static final String replyToIssueActivity = "ReplyToIssueActivity";
public static final String tagDraftsBottomSheet = "BottomSheetDraftsFragment";
public static final String userAccountsApi = "UserAccountsApi";
+ public static final String publicOrganizations = "PublicOrganizations";
// issues variables
public static final int issuesPageInit = 1;
@@ -51,6 +52,9 @@ public class Constants {
public static final int defaultPollingDelay = 15;
public static final int maximumPollingDelay = 720;
+ // public organizations
+ public static final int publicOrganizationsPageInit = 1;
+
public static final int maximumFileViewerSize = 3 * 1024 * 1024;
public static final String mainNotificationChannelId = "main_channel";
diff --git a/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java b/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java
new file mode 100644
index 00000000..c2febdac
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java
@@ -0,0 +1,46 @@
+package org.mian.gitnex.helpers;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+import com.google.android.material.snackbar.Snackbar;
+import org.mian.gitnex.R;
+
+/**
+ * Author M M Arif
+ */
+
+public class SnackBar {
+
+ public static void info(Context context, View view, String message) {
+ Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
+ View sbView = snackBar.getView();
+ TextView textView = sbView.findViewById(R.id.snackbar_text);
+ textView.setTextColor(context.getResources().getColor(R.color.colorWhite));
+ snackBar.show();
+ }
+
+ public static void success(Context context, View view, String message) {
+ Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
+ View sbView = snackBar.getView();
+ TextView textView = sbView.findViewById(R.id.snackbar_text);
+ textView.setTextColor(context.getResources().getColor(R.color.colorLightGreen));
+ snackBar.show();
+ }
+
+ public static void warning(Context context, View view, String message) {
+ Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
+ View sbView = snackBar.getView();
+ TextView textView = sbView.findViewById(R.id.snackbar_text);
+ textView.setTextColor(context.getResources().getColor(R.color.lightYellow));
+ snackBar.show();
+ }
+
+ public static void error(Context context, View view, String message) {
+ Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
+ View sbView = snackBar.getView();
+ TextView textView = sbView.findViewById(R.id.snackbar_text);
+ textView.setTextColor(context.getResources().getColor(R.color.darkRed));
+ snackBar.show();
+ }
+}
diff --git a/app/src/main/res/layout/activity_add_collaborator_to_repository.xml b/app/src/main/res/layout/activity_add_collaborator_to_repository.xml
index 218adf7d..34114444 100644
--- a/app/src/main/res/layout/activity_add_collaborator_to_repository.xml
+++ b/app/src/main/res/layout/activity_add_collaborator_to_repository.xml
@@ -10,6 +10,7 @@
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
-
@@ -11,6 +11,7 @@
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
-
@@ -11,6 +11,7 @@
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
+ android:src="@drawable/ic_close" />
+ android:elevation="0dp">
+ android:src="@drawable/ic_close" />
-
@@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
@@ -10,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
@@ -10,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
@@ -10,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
@@ -10,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
-
@@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
+ app:elevation="0dp"
android:theme="@style/Widget.AppCompat.SearchView">
+
+
diff --git a/app/src/main/res/layout/fragment_organizations.xml b/app/src/main/res/layout/fragment_organizations.xml
index e7a0ae12..7af6fb1d 100644
--- a/app/src/main/res/layout/fragment_organizations.xml
+++ b/app/src/main/res/layout/fragment_organizations.xml
@@ -27,6 +27,15 @@
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
+
+
-
+ android:gravity="center_vertical"
+ tools:ignore="UseCompoundDrawables">
diff --git a/app/src/main/res/layout/list_notifications.xml b/app/src/main/res/layout/list_notifications.xml
index 588bccce..33b8a273 100644
--- a/app/src/main/res/layout/list_notifications.xml
+++ b/app/src/main/res/layout/list_notifications.xml
@@ -6,7 +6,7 @@
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
android:padding="16dp"
- android:orientation="vertical">
+ android:orientation="horizontal">