Use paginations (#1089)

Closes #278

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1089
Reviewed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
M M Arif 2022-04-04 10:00:54 +02:00
parent 6654ba4abd
commit 5c0950d287
38 changed files with 1041 additions and 1693 deletions

View File

@ -107,7 +107,7 @@ dependencies {
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.1.3"
implementation "org.codeberg.gitnex:tea4j:1.1.4"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.github.chrisvest:stormpot:2.4.2'

View File

@ -1,6 +1,5 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
@ -10,96 +9,101 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.AdminGetUsersAdapter;
import org.mian.gitnex.databinding.ActivityAdminGetUsersBinding;
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.structs.BottomSheetListener;
import org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class AdminGetUsersActivity extends BaseActivity implements BottomSheetListener {
private View.OnClickListener onClickListener;
private AdminGetUsersAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataUsers;
private Boolean searchFilter = false;
private View.OnClickListener onClickListener;
private ActivityAdminGetUsersBinding activityAdminGetUsersBinding;
private AdminGetUsersAdapter adapter;
private int page = 1;
private int resultLimit = Constants.resultLimitNewGiteaInstances;
private Boolean searchFilter = false;
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
ActivityAdminGetUsersBinding activityAdminGetUsersBinding = ActivityAdminGetUsersBinding.inflate(getLayoutInflater());
setContentView(activityAdminGetUsersBinding.getRoot());
activityAdminGetUsersBinding = ActivityAdminGetUsersBinding.inflate(getLayoutInflater());
setContentView(activityAdminGetUsersBinding.getRoot());
ImageView closeActivity = activityAdminGetUsersBinding.close;
noDataUsers = activityAdminGetUsersBinding.noDataUsers;
mRecyclerView = activityAdminGetUsersBinding.recyclerView;
Toolbar toolbar = activityAdminGetUsersBinding.toolbar;
setSupportActionBar(toolbar);
final SwipeRefreshLayout swipeRefresh = activityAdminGetUsersBinding.pullToRefresh;
initCloseListener();
activityAdminGetUsersBinding.close.setOnClickListener(onClickListener);
Toolbar toolbar = activityAdminGetUsersBinding.toolbar;
setSupportActionBar(toolbar);
activityAdminGetUsersBinding.recyclerView.setHasFixedSize(true);
activityAdminGetUsersBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(activityAdminGetUsersBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
activityAdminGetUsersBinding.recyclerView.addItemDecoration(dividerItemDecoration);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
activityAdminGetUsersBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
page = 1;
activityAdminGetUsersBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(getAccount().getAuthorization());
activityAdminGetUsersBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
fetchDataAsync(getAccount().getAuthorization());
};
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
private void fetchDataAsync(String instanceToken) {
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, getAccount().getAuthorization());
AdminGetUsersViewModel adminUsersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class);
}, 500));
adminUsersModel.getUsersList(instanceToken, page, resultLimit, ctx).observe(this, adminUsersListMain -> {
fetchDataAsync(ctx, getAccount().getAuthorization());
adapter = new AdminGetUsersAdapter(adminUsersListMain, ctx);
adapter.setLoadMoreListener(new AdminGetUsersAdapter.OnLoadMoreListener() {
}
@Override
public void onLoadMore() {
private void fetchDataAsync(Context ctx, String instanceToken) {
page += 1;
AdminGetUsersViewModel.loadMoreUsersList(instanceToken, page, resultLimit, ctx, adapter);
activityAdminGetUsersBinding.progressBar.setVisibility(View.VISIBLE);
}
AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class);
@Override
public void onLoadFinished() {
usersModel.getUsersList(ctx, instanceToken).observe(this, usersListMain -> {
activityAdminGetUsersBinding.progressBar.setVisibility(View.GONE);
}
});
adapter = new AdminGetUsersAdapter(ctx, usersListMain);
if(adapter.getItemCount() > 0) {
if(adapter.getItemCount() > 0) {
activityAdminGetUsersBinding.recyclerView.setAdapter(adapter);
activityAdminGetUsersBinding.noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
adapter.notifyDataChanged();
activityAdminGetUsersBinding.recyclerView.setAdapter(adapter);
activityAdminGetUsersBinding.noDataUsers.setVisibility(View.VISIBLE);
}
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
});
}
activityAdminGetUsersBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
@ -134,10 +138,8 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetLi
adapter.getFilter().filter(newText);
return false;
}
});
}
}, 500);
return true;
@ -168,16 +170,12 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetLi
@Override
public void onButtonClicked(String text) {
switch (text) {
case "newUser":
startActivity(new Intent(AdminGetUsersActivity.this, CreateNewUserActivity.class));
break;
}
if("newUser".equals(text)) {
startActivity(new Intent(AdminGetUsersActivity.this, CreateNewUserActivity.class));
}
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -16,7 +16,6 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.app.NotificationCompat;
import com.vdurmont.emoji.EmojiParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.gitnex.tea4j.models.Files;
import org.mian.gitnex.R;

View File

@ -62,7 +62,7 @@ import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
* @author M M Arif
*/
@SuppressWarnings("ConstantConditions")

View File

@ -11,7 +11,7 @@ import java.util.Arrays;
import java.util.List;
/**
* Author M M Arif
* @author M M Arif
*/
public class SettingsGeneralActivity extends BaseActivity {

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
@ -24,122 +25,148 @@ import java.util.ArrayList;
import java.util.List;
/**
* Author M M Arif
* @author M M Arif
*/
public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdapter.UsersViewHolder> implements Filterable {
public class AdminGetUsersAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private final List<UserInfo> usersList;
private final Context context;
private final List<UserInfo> usersListFull;
private List<UserInfo> usersList;
private final List<UserInfo> usersListFull;
private final Context context;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
class UsersViewHolder extends RecyclerView.ViewHolder {
public AdminGetUsersAdapter(List<UserInfo> usersListMain, Context ctx) {
this.context = ctx;
this.usersList = usersListMain;
usersListFull = new ArrayList<>(usersList);
}
private String userLoginId;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
return new AdminGetUsersAdapter.ReposHolder(inflater.inflate(R.layout.list_admin_users, parent, false));
}
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userEmail;
private final ImageView userRole;
private final TextView userName;
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
private UsersViewHolder(View itemView) {
((AdminGetUsersAdapter.ReposHolder) holder).bindData(usersList.get(position));
}
super(itemView);
@Override
public int getItemViewType(int position) {
return position;
}
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userEmail = itemView.findViewById(R.id.userEmail);
userRole = itemView.findViewById(R.id.userRole);
@Override
public int getItemCount() {
return usersList.size();
}
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
class ReposHolder extends RecyclerView.ViewHolder {
userAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
private String userLoginId;
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userEmail;
private final ImageView userRole;
private final TextView userName;
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
ReposHolder(View itemView) {
public AdminGetUsersAdapter(Context ctx, List<UserInfo> usersListMain) {
super(itemView);
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userEmail = itemView.findViewById(R.id.userEmail);
userRole = itemView.findViewById(R.id.userRole);
this.context = ctx;
this.usersList = usersListMain;
usersListFull = new ArrayList<>(usersList);
}
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
@NonNull
@Override
public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_admin_users, parent, false);
return new AdminGetUsersAdapter.UsersViewHolder(v);
}
void bindData(UserInfo users) {
@Override
public void onBindViewHolder(@NonNull AdminGetUsersAdapter.UsersViewHolder holder, int position) {
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
UserInfo currentItem = usersList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
userLoginId = users.getLogin();
holder.userLoginId = currentItem.getLogin();
if(!users.getFullname().equals("")) {
if(!currentItem.getFullname().equals("")) {
userFullName.setText(Html.fromHtml(users.getFullname()));
userName.setText(context.getResources().getString(R.string.usernameWithAt, users.getUsername()));
}
else {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
else {
userFullName.setText(context.getResources().getString(R.string.usernameWithAt, users.getUsername()));
userName.setVisibility(View.GONE);
}
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setVisibility(View.GONE);
}
if(!users.getEmail().equals("")) {
userEmail.setText(users.getEmail());
}
else {
userEmail.setVisibility(View.GONE);
}
if(!currentItem.getEmail().equals("")) {
if(users.getIs_admin()) {
holder.userEmail.setText(currentItem.getEmail());
}
else {
userRole.setVisibility(View.VISIBLE);
TextDrawable drawable = TextDrawable.builder().beginConfig()
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null)).fontSize(44).width(180).height(60)
.endConfig().buildRoundRect(context.getResources().getString(R.string.userRoleAdmin).toLowerCase(), ResourcesCompat.getColor(context.getResources(), R.color.releasePre, null), 8);
userRole.setImageDrawable(drawable);
}
else {
holder.userEmail.setVisibility(View.GONE);
}
userRole.setVisibility(View.GONE);
}
if(currentItem.getIs_admin()) {
PicassoService.getInstance(context).get().load(users.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(userAvatar);
}
}
holder.userRole.setVisibility(View.VISIBLE);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null))
.fontSize(44)
.width(180)
.height(60)
.endConfig()
.buildRoundRect(context.getResources().getString(R.string.userRoleAdmin).toLowerCase(), ResourcesCompat.getColor(context.getResources(), R.color.releasePre, null), 8);
holder.userRole.setImageDrawable(drawable);
}
else {
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if(!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
holder.userRole.setVisibility(View.GONE);
}
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
loadMoreListener.onLoadFinished();
}
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();
}
@Override
public int getItemCount() {
return usersList.size();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserInfo> list) {
usersList = list;
notifyDataChanged();
}
@Override
public Filter getFilter() {
@ -175,8 +202,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
usersList.clear();
usersList.addAll((List) results.values);
notifyDataSetChanged();
notifyDataChanged();
}
};
}

View File

@ -22,119 +22,160 @@ import java.util.ArrayList;
import java.util.List;
/**
* Author M M Arif
* @author M M Arif
*/
public class OrganizationsListAdapter extends RecyclerView.Adapter<OrganizationsListAdapter.OrganizationsViewHolder> implements Filterable {
public class OrganizationsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private final List<UserOrganizations> orgList;
private final Context context;
private final List<UserOrganizations> orgListFull;
private final Context context;
private List<UserOrganizations> orgList;
private final List<UserOrganizations> orgListFull;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
static class OrganizationsViewHolder extends RecyclerView.ViewHolder {
public OrganizationsListAdapter(List<UserOrganizations> orgListMain, Context ctx) {
this.context = ctx;
this.orgList = orgListMain;
orgListFull = new ArrayList<>(orgList);
}
private UserOrganizations userOrganizations;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
return new OrganizationsListAdapter.OrgHolder(inflater.inflate(R.layout.list_organizations, parent, false));
}
private final ImageView image;
private final TextView orgName;
private final TextView orgDescription;
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
private OrganizationsViewHolder(View itemView) {
super(itemView);
orgName = itemView.findViewById(R.id.orgName);
orgDescription = itemView.findViewById(R.id.orgDescription);
image = itemView.findViewById(R.id.imageAvatar);
((OrganizationsListAdapter.OrgHolder) holder).bindData(orgList.get(position));
}
itemView.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, OrganizationDetailActivity.class);
intent.putExtra("orgName", userOrganizations.getUsername());
context.startActivity(intent);
});
}
}
@Override
public int getItemViewType(int position) {
return position;
}
public OrganizationsListAdapter(Context ctx, List<UserOrganizations> orgsListMain) {
@Override
public int getItemCount() {
return orgList.size();
}
this.context = ctx;
this.orgList = orgsListMain;
orgListFull = new ArrayList<>(orgList);
}
class OrgHolder extends RecyclerView.ViewHolder {
@NonNull
@Override
public OrganizationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
private UserOrganizations userOrganizations;
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_organizations, parent, false);
return new OrganizationsViewHolder(v);
}
private final ImageView image;
private final TextView orgName;
private final TextView orgDescription;
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) {
OrgHolder(View itemView) {
UserOrganizations currentItem = orgList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
super(itemView);
orgName = itemView.findViewById(R.id.orgName);
orgDescription = itemView.findViewById(R.id.orgDescription);
image = itemView.findViewById(R.id.imageAvatar);
holder.userOrganizations = currentItem;
holder.orgName.setText(currentItem.getUsername());
itemView.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, OrganizationDetailActivity.class);
intent.putExtra("orgName", userOrganizations.getUsername());
context.startActivity(intent);
});
}
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
void bindData(UserOrganizations org) {
if(!currentItem.getDescription().equals("")) {
holder.orgDescription.setVisibility(View.VISIBLE);
holder.orgDescription.setText(currentItem.getDescription());
}
else {
holder.orgDescription.setVisibility(View.GONE);
}
}
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
@Override
public int getItemCount() {
return orgList.size();
}
this.userOrganizations = org;
orgName.setText(org.getUsername());
@Override
public Filter getFilter() {
return orgFilter;
}
PicassoService.getInstance(context).get().load(org.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(image);
private final Filter orgFilter = new Filter() {
if(!org.getDescription().equals("")) {
orgDescription.setVisibility(View.VISIBLE);
orgDescription.setText(org.getDescription());
}
else {
orgDescription.setVisibility(View.GONE);
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
}
List<UserOrganizations> filteredList = new ArrayList<>();
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if(!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
if (constraint == null || constraint.length() == 0) {
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
loadMoreListener.onLoadFinished();
}
filteredList.addAll(orgListFull);
}
else {
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();
}
String filterPattern = constraint.toString().toLowerCase().trim();
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
for (UserOrganizations item : orgListFull) {
if (item.getUsername().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
public void updateList(List<UserOrganizations> list) {
orgList = list;
notifyDataChanged();
}
FilterResults results = new FilterResults();
results.values = filteredList;
@Override
public Filter getFilter() {
return orgFilter;
}
return results;
}
private final Filter orgFilter = new Filter() {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
orgList.clear();
orgList.addAll((List) results.values);
notifyDataSetChanged();
}
};
List<UserOrganizations> filteredList = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(orgListFull);
}
else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(UserOrganizations item : orgListFull) {
if(item.getUsername().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
orgList.clear();
orgList.addAll((List) results.values);
notifyDataChanged();
}
};
}

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -36,16 +37,53 @@ import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
* @author M M Arif
*/
public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.ReposViewHolder> implements Filterable {
public class ReposListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private final List<UserRepositories> reposList;
private final Context context;
private List<UserRepositories> reposList;
private final List<UserRepositories> reposListFull;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
private final TinyDB tinyDb;
static class ReposViewHolder extends RecyclerView.ViewHolder {
public ReposListAdapter(List<UserRepositories> reposListMain, Context ctx) {
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
this.tinyDb = TinyDB.getInstance(context);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
return new ReposListAdapter.ReposHolder(inflater.inflate(R.layout.list_repositories, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
((ReposListAdapter.ReposHolder) holder).bindData(reposList.get(position));
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
return reposList.size();
}
class ReposHolder extends RecyclerView.ViewHolder {
private UserRepositories userRepositories;
@ -58,7 +96,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private final TextView repoLastUpdated;
private final View spacerView;
private ReposViewHolder(View itemView) {
ReposHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
@ -94,108 +132,111 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
});
}
}
@SuppressLint("SetTextI18n")
void bindData(UserRepositories repositories) {
public ReposListAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.userRepositories = repositories;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
orgName.setText(repositories.getFullName().split("/")[0]);
repoName.setText(repositories.getFullName().split("/")[1]);
repoStars.setText(repositories.getStars_count());
@NonNull
@Override
public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
int color = generator.getColor(repositories.getName());
String firstCharacter = String.valueOf(repositories.getFullName().charAt(0));
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new ReposViewHolder(v);
}
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
@Override
public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) {
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
if(repositories.getAvatar_url() != null) {
if(!repositories.getAvatar_url().equals("")) {
PicassoService.getInstance(context).get().load(repositories.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(image);
}
else {
image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
if(currentItem.getUpdated_at() != null) {
if(repositories.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(repositories.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repositories.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(repositories.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(repositories.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
}
else {
holder.repoLastUpdated.setVisibility(View.GONE);
}
else {
repoLastUpdated.setVisibility(View.GONE);
}
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
holder.spacerView.setVisibility(View.GONE);
}
else {
holder.repoDescription.setVisibility(View.GONE);
holder.spacerView.setVisibility(View.VISIBLE);
}
if(!repositories.getDescription().equals("")) {
repoDescription.setVisibility(View.VISIBLE);
repoDescription.setText(repositories.getDescription());
spacerView.setVisibility(View.GONE);
}
else {
repoDescription.setVisibility(View.GONE);
spacerView.setVisibility(View.VISIBLE);
}
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(context);
if(isRepoAdmin == null) {
isRepoAdmin = new CheckBox(context);
}
isRepoAdmin.setChecked(repositories.getPermissions().isAdmin());
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
}
@Override
public int getItemCount() {
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if(!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
return reposList.size();
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
loadMoreListener.onLoadFinished();
}
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserRepositories> list) {
reposList = list;
notifyDataChanged();
}
@Override
public Filter getFilter() {
return reposFilter;
}
@ -230,8 +271,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
reposList.clear();
reposList.addAll((List) results.values);
notifyDataSetChanged();
notifyDataChanged();
}
};
}

View File

@ -1,238 +0,0 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesByOrgAdapter.OrgReposViewHolder> implements Filterable {
private final List<UserRepositories> reposList;
private final Context context;
private final List<UserRepositories> reposListFull;
static class OrgReposViewHolder extends RecyclerView.ViewHolder {
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private final TextView repoStars;
private final TextView repoLastUpdated;
private final View spacerView;
private OrgReposViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
spacerView = itemView.findViewById(R.id.spacerView);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
RepositoryContext repo = new RepositoryContext(userRepositories, context);
Intent intent = repo.getIntent(context, RepoDetailActivity.class);
int currentActiveAccountId = TinyDB.getInstance(context).getInt("currentActiveAccountId");
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repo.getOwner(), repo.getName());
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repo.getOwner(), repo.getName());
repo.setRepositoryId((int) id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repo.getOwner(), repo.getName());
repo.setRepositoryId(data.getRepositoryId());
}
context.startActivity(intent);
});
}
}
public RepositoriesByOrgAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
@NonNull
@Override
public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) {
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
if(currentItem.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.repoLastUpdated.setVisibility(View.GONE);
}
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
holder.spacerView.setVisibility(View.GONE);
}
else {
holder.repoDescription.setVisibility(View.GONE);
holder.spacerView.setVisibility(View.VISIBLE);
}
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
}
@Override
public int getItemCount() {
return reposList.size();
}
@Override
public Filter getFilter() {
return orgReposFilter;
}
private final Filter orgReposFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<UserRepositories> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(reposListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (UserRepositories item : reposListFull) {
if (item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
reposList.clear();
reposList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}

View File

@ -11,105 +11,101 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.CreateRepoActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.databinding.FragmentMyRepositoriesBinding;
import org.mian.gitnex.viewmodels.MyRepositoriesViewModel;
import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.viewmodels.RepositoriesViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class MyRepositoriesFragment extends Fragment {
private ProgressBar mProgressBar;
private RecyclerView mRecyclerView;
private ReposListAdapter adapter;
private ExtendedFloatingActionButton createNewRepo;
private TextView noDataMyRepo;
private FragmentRepositoriesBinding fragmentRepositoriesBinding;
private ReposListAdapter adapter;
private int page = 1;
private final int resultLimit = Constants.resultLimitNewGiteaInstances;
private int pageSize = 1;
private int resultLimit = 50;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navMyRepos));
final String userLogin = ((BaseActivity) requireActivity()).getAccount().getAccount().getUserName();
FragmentMyRepositoriesBinding fragmentMyRepositoriesBinding = FragmentMyRepositoriesBinding.inflate(inflater, container, false);
fragmentRepositoriesBinding.addNewRepo.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
setHasOptionsMenu(true);
fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentRepositoriesBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
final String userLogin = ((BaseActivity) requireActivity()).getAccount().getAccount().getUserName();
fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
final SwipeRefreshLayout swipeRefresh = fragmentMyRepositoriesBinding.pullToRefresh;
page = 1;
fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), userLogin);
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navMyRepos));
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), userLogin);
noDataMyRepo = fragmentMyRepositoriesBinding.noDataMyRepo;
mProgressBar = fragmentMyRepositoriesBinding.progressBar;
mRecyclerView = fragmentMyRepositoriesBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
return fragmentRepositoriesBinding.getRoot();
};
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
private void fetchDataAsync(String instanceToken, String userLogin) {
createNewRepo = fragmentMyRepositoriesBinding.addNewRepo;
createNewRepo.setOnClickListener(view -> {
RepositoriesViewModel reposModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
reposModel.getRepositories(instanceToken, page, resultLimit, userLogin, "myRepos", null, getContext()).observe(getViewLifecycleOwner(), reposListMain -> {
});
adapter = new ReposListAdapter(reposListMain, getContext());
adapter.setLoadMoreListener(new ReposListAdapter.OnLoadMoreListener() {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
@Override
public void onLoadMore() {
if (dy > 0 && createNewRepo.isShown()) {
createNewRepo.setVisibility(View.GONE);
} else if (dy < 0) {
createNewRepo.setVisibility(View.VISIBLE);
}
page += 1;
RepositoriesViewModel.loadMoreRepos(instanceToken, page, resultLimit, userLogin, "myRepos", null, getContext(), adapter);
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}
}
@Override
public void onLoadFinished() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
if(adapter.getItemCount() > 0) {
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataChanged();
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
}
swipeRefresh.setRefreshing(false);
MyRepositoriesViewModel.loadMyReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), userLogin, getContext(), pageSize, resultLimit);
}, 50));
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), userLogin, pageSize, resultLimit);
return fragmentMyRepositoriesBinding.getRoot();
}
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onResume() {
@ -117,34 +113,12 @@ public class MyRepositoriesFragment extends Fragment {
final String userLogin = ((BaseActivity) requireActivity()).getAccount().getAccount().getUserName();
if(MainActivity.repoCreated) {
MyRepositoriesViewModel.loadMyReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), userLogin, getContext(), pageSize, resultLimit);
RepositoriesViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), page, resultLimit, userLogin, "myRepos", null, getContext() );
MainActivity.repoCreated = false;
}
}
private void fetchDataAsync(String instanceToken, String userLogin, int pageSize, int resultLimit) {
MyRepositoriesViewModel myRepoModel = new ViewModelProvider(this).get(MyRepositoriesViewModel.class);
myRepoModel.getCurrentUserRepositories(instanceToken, userLogin, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(),
myReposListMain -> {
adapter = new ReposListAdapter(getContext(), myReposListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataMyRepo.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataMyRepo.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
@ -154,11 +128,6 @@ public class MyRepositoriesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
@ -168,7 +137,7 @@ public class MyRepositoriesFragment extends Fragment {
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
if(fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;

View File

@ -11,128 +11,112 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.CreateOrganizationActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.OrganizationsListAdapter;
import org.mian.gitnex.databinding.FragmentOrganizationsBinding;
import org.mian.gitnex.viewmodels.OrganizationListViewModel;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.viewmodels.OrganizationsViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class OrganizationsFragment extends Fragment {
public static boolean orgCreated = false;
private FragmentOrganizationsBinding fragmentOrganizationsBinding;
private OrganizationsListAdapter adapter;
private int page = 1;
private final int resultLimit = Constants.resultLimitNewGiteaInstances;
private ProgressBar mProgressBar;
private OrganizationsListAdapter adapter;
private RecyclerView mRecyclerView;
private ExtendedFloatingActionButton createNewOrganization;
private TextView noDataOrg;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
fragmentOrganizationsBinding = FragmentOrganizationsBinding.inflate(inflater, container, false);
FragmentOrganizationsBinding fragmentOrganizationsBinding = FragmentOrganizationsBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
setHasOptionsMenu(true);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navOrg));
final SwipeRefreshLayout swipeRefresh = fragmentOrganizationsBinding.pullToRefresh;
fragmentOrganizationsBinding.addNewOrganization.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), CreateOrganizationActivity.class);
startActivity(intent);
});
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navOrg));
fragmentOrganizationsBinding.recyclerView.setHasFixedSize(true);
fragmentOrganizationsBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentOrganizationsBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
fragmentOrganizationsBinding.recyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = fragmentOrganizationsBinding.progressBar;
noDataOrg = fragmentOrganizationsBinding.noDataOrg;
mRecyclerView = fragmentOrganizationsBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fragmentOrganizationsBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
page = 1;
fragmentOrganizationsBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
fragmentOrganizationsBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
createNewOrganization = fragmentOrganizationsBinding.addNewOrganization;
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
createNewOrganization.setOnClickListener(view -> {
return fragmentOrganizationsBinding.getRoot();
};
Intent intent = new Intent(view.getContext(), CreateOrganizationActivity.class);
startActivity(intent);
});
private void fetchDataAsync(String instanceToken) {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0 && createNewOrganization.isShown()) {
createNewOrganization.setVisibility(View.GONE);
} else if (dy < 0 ) {
createNewOrganization.setVisibility(View.VISIBLE);
}
}
OrganizationsViewModel orgModel = new ViewModelProvider(this).get(OrganizationsViewModel.class);
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
orgModel.getUserOrg(instanceToken, page, resultLimit, getContext()).observe(getViewLifecycleOwner(), orgListMain -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
adapter = new OrganizationsListAdapter(orgListMain, getContext());
adapter.setLoadMoreListener(new OrganizationsListAdapter.OnLoadMoreListener() {
swipeRefresh.setRefreshing(false);
OrganizationListViewModel.loadOrgsList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext());
@Override
public void onLoadMore() {
}, 50));
page += 1;
OrganizationsViewModel.loadMoreOrgList(instanceToken, page, resultLimit, getContext(), adapter);
fragmentOrganizationsBinding.progressBar.setVisibility(View.VISIBLE);
}
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
@Override
public void onLoadFinished() {
return fragmentOrganizationsBinding.getRoot();
fragmentOrganizationsBinding.progressBar.setVisibility(View.GONE);
}
});
}
if(adapter.getItemCount() > 0) {
fragmentOrganizationsBinding.recyclerView.setAdapter(adapter);
fragmentOrganizationsBinding.noDataOrg.setVisibility(View.GONE);
}
else {
adapter.notifyDataChanged();
fragmentOrganizationsBinding.recyclerView.setAdapter(adapter);
fragmentOrganizationsBinding.noDataOrg.setVisibility(View.VISIBLE);
}
fragmentOrganizationsBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onResume(){
super.onResume();
if(orgCreated) {
OrganizationListViewModel.loadOrgsList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext());
OrganizationsViewModel.loadOrgList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), page, resultLimit, getContext());
orgCreated = false;
}
}
private void fetchDataAsync(String instanceToken) {
OrganizationListViewModel orgModel = new ViewModelProvider(this).get(OrganizationListViewModel.class);
orgModel.getUserOrgs(instanceToken, getContext()).observe(getViewLifecycleOwner(), orgsListMain -> {
adapter = new OrganizationsListAdapter(getContext(), orgsListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataOrg.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataOrg.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
@ -142,11 +126,6 @@ public class OrganizationsFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
@ -156,13 +135,11 @@ public class OrganizationsFragment extends Fragment {
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
if(fragmentOrganizationsBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -10,93 +10,115 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.RepositoriesByOrgAdapter;
import org.mian.gitnex.databinding.FragmentRepositoriesByOrgBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.viewmodels.RepositoriesByOrgViewModel;
import java.util.List;
import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.viewmodels.RepositoriesViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class RepositoriesByOrgFragment extends Fragment {
private ProgressBar mProgressBar;
private RepositoriesByOrgAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noData;
private static String orgNameF = "param2";
private String orgName;
private int pageSize = 1;
private int resultLimit = 50;
private FragmentRepositoriesBinding fragmentRepositoriesBinding;
private ReposListAdapter adapter;
private int page = 1;
private final int resultLimit = Constants.resultLimitNewGiteaInstances;
private static final String getOrgName = null;
private String orgName;
public RepositoriesByOrgFragment() {
}
public RepositoriesByOrgFragment() { }
public static RepositoriesByOrgFragment newInstance(String param1) {
public static RepositoriesByOrgFragment newInstance(String orgName) {
RepositoriesByOrgFragment fragment = new RepositoriesByOrgFragment();
Bundle args = new Bundle();
args.putString(orgNameF, param1);
args.putString(getOrgName, orgName);
fragment.setArguments(args);
return fragment;
}
@Override
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
orgName = getArguments().getString(orgNameF);
orgName = getArguments().getString(getOrgName);
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentRepositoriesByOrgBinding fragmentRepositoriesByOrgBinding = FragmentRepositoriesByOrgBinding.inflate(inflater, container, false);
fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
noData = fragmentRepositoriesByOrgBinding.noData;
setHasOptionsMenu(true);
final SwipeRefreshLayout swipeRefresh = fragmentRepositoriesByOrgBinding.pullToRefresh;
fragmentRepositoriesBinding.addNewRepo.setVisibility(View.GONE);
mRecyclerView = fragmentRepositoriesByOrgBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentRepositoriesBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
mProgressBar = fragmentRepositoriesByOrgBinding.progressBar;
page = 1;
fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
swipeRefresh.setRefreshing(false);
RepositoriesByOrgViewModel.loadOrgRepos(((BaseActivity) requireActivity()).getAccount().getAuthorization(), orgName, getContext(), pageSize, resultLimit);
return fragmentRepositoriesBinding.getRoot();
};
}, 200));
private void fetchDataAsync(String instanceToken) {
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), orgName, pageSize, resultLimit);
RepositoriesViewModel reposModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
return fragmentRepositoriesByOrgBinding.getRoot();
}
reposModel.getRepositories(instanceToken, page, resultLimit, "", "org", orgName, getContext()).observe(getViewLifecycleOwner(), reposListMain -> {
adapter = new ReposListAdapter(reposListMain, getContext());
adapter.setLoadMoreListener(new ReposListAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
page += 1;
RepositoriesViewModel.loadMoreRepos(instanceToken, page, resultLimit, "", "org", orgName, getContext(), adapter);
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadFinished() {
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
}
});
if(adapter.getItemCount() > 0) {
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataChanged();
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
}
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onResume() {
@ -104,51 +126,21 @@ public class RepositoriesByOrgFragment extends Fragment {
super.onResume();
if(MainActivity.repoCreated) {
RepositoriesByOrgViewModel.loadOrgRepos(((BaseActivity) requireActivity()).getAccount().getAuthorization(), orgName, getContext(), pageSize, resultLimit);
RepositoriesViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), page, resultLimit, null, "org", orgName, getContext());
MainActivity.repoCreated = false;
}
}
private void fetchDataAsync(String instanceToken, String owner, int pageSize, int resultLimit) {
RepositoriesByOrgViewModel orgRepoModel = new ViewModelProvider(this).get(RepositoriesByOrgViewModel.class);
orgRepoModel.getRepositoriesByOrg(instanceToken, owner, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer<List<UserRepositories>>() {
@Override
public void onChanged(@Nullable List<UserRepositories> orgReposListMain) {
adapter = new RepositoriesByOrgAdapter(getContext(), orgReposListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.hasNetworkConnection(requireContext());
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
@ -158,12 +150,11 @@ public class RepositoriesByOrgFragment extends Fragment {
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
if(fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -11,127 +11,111 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.CreateRepoActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
import org.mian.gitnex.viewmodels.RepositoriesListViewModel;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.viewmodels.RepositoriesViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class RepositoriesFragment extends Fragment {
private ProgressBar mProgressBar;
private RecyclerView mRecyclerView;
private ReposListAdapter adapter;
private ExtendedFloatingActionButton createNewRepo;
private TextView noDataRepo;
private final int pageSize = 1;
private final int resultLimit = 50;
private FragmentRepositoriesBinding fragmentRepositoriesBinding;
private ReposListAdapter adapter;
private int page = 1;
private final int resultLimit = Constants.resultLimitNewGiteaInstances;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentRepositoriesBinding fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
setHasOptionsMenu(true);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navRepos));
final SwipeRefreshLayout swipeRefresh = fragmentRepositoriesBinding.pullToRefresh;
fragmentRepositoriesBinding.addNewRepo.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navRepos));
fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentRepositoriesBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
noDataRepo = fragmentRepositoriesBinding.noData;
mProgressBar = fragmentRepositoriesBinding.progressBar;
mRecyclerView = fragmentRepositoriesBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
page = 1;
fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
createNewRepo = fragmentRepositoriesBinding.addNewRepo;
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
createNewRepo.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
return fragmentRepositoriesBinding.getRoot();
};
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0 && createNewRepo.isShown()) {
createNewRepo.setVisibility(View.GONE);
}
else if (dy < 0 ) {
createNewRepo.setVisibility(View.VISIBLE);
}
}
private void fetchDataAsync(String instanceToken) {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
RepositoriesViewModel reposModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
reposModel.getRepositories(instanceToken, page, resultLimit, null, "repos", null, getContext()).observe(getViewLifecycleOwner(), reposListMain -> {
swipeRefresh.setRefreshing(false);
RepositoriesListViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext(), pageSize, resultLimit);
adapter = new ReposListAdapter(reposListMain, getContext());
adapter.setLoadMoreListener(new ReposListAdapter.OnLoadMoreListener() {
}, 50));
@Override
public void onLoadMore() {
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), pageSize, resultLimit);
return fragmentRepositoriesBinding.getRoot();
page += 1;
RepositoriesViewModel.loadMoreRepos(instanceToken, page, resultLimit, null, "repos", null, getContext(), adapter);
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}
}
@Override
public void onLoadFinished() {
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
}
});
if(adapter.getItemCount() > 0) {
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataChanged();
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
}
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onResume() {
super.onResume();
if(MainActivity.repoCreated) {
RepositoriesListViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext(), pageSize, resultLimit);
RepositoriesViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), page, resultLimit, "", "repos", null, getContext());
MainActivity.repoCreated = false;
}
}
private void fetchDataAsync(String instanceToken, int pageSize, int resultLimit) {
RepositoriesListViewModel repoModel = new ViewModelProvider(this).get(RepositoriesListViewModel.class);
repoModel.getUserRepositories(instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(),
reposListMain -> {
adapter = new ReposListAdapter(getContext(), reposListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataRepo.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataRepo.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
@ -150,12 +134,11 @@ public class RepositoriesFragment extends Fragment {
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
if(fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
}

View File

@ -11,117 +11,100 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.CreateRepoActivity;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.databinding.FragmentStarredRepositoriesBinding;
import org.mian.gitnex.viewmodels.StarredRepositoriesViewModel;
import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.viewmodels.RepositoriesViewModel;
/**
* Author M M Arif
* @author M M Arif
*/
public class StarredRepositoriesFragment extends Fragment {
private ProgressBar mProgressBar;
private RecyclerView mRecyclerView;
private ReposListAdapter adapter;
private ExtendedFloatingActionButton createNewRepo;
private TextView noData;
private int pageSize = 1;
private int resultLimit = 50;
private FragmentRepositoriesBinding fragmentRepositoriesBinding;
private ReposListAdapter adapter;
private int page = 1;
private final int resultLimit = Constants.resultLimitNewGiteaInstances;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentStarredRepositoriesBinding fragmentStarredRepositoriesBinding = FragmentStarredRepositoriesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
final SwipeRefreshLayout swipeRefresh = fragmentStarredRepositoriesBinding.pullToRefresh;
setHasOptionsMenu(true);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navStarredRepos));
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navStarredRepos));
fragmentRepositoriesBinding.addNewRepo.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
noData = fragmentStarredRepositoriesBinding.noData;
mProgressBar = fragmentStarredRepositoriesBinding.progressBar;
mRecyclerView = fragmentStarredRepositoriesBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentRepositoriesBinding.recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
createNewRepo = fragmentStarredRepositoriesBinding.addNewRepo;
page = 1;
fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
createNewRepo.setOnClickListener(view -> {
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization());
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
return fragmentRepositoriesBinding.getRoot();
};
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0 && createNewRepo.isShown()) {
createNewRepo.setVisibility(View.GONE);
} else if (dy < 0 ) {
createNewRepo.setVisibility(View.VISIBLE);
private void fetchDataAsync(String instanceToken) {
}
}
RepositoriesViewModel reposModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
reposModel.getRepositories(instanceToken, page, resultLimit, "", "starredRepos", null, getContext()).observe(getViewLifecycleOwner(), reposListMain -> {
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
adapter = new ReposListAdapter(reposListMain, getContext());
adapter.setLoadMoreListener(new ReposListAdapter.OnLoadMoreListener() {
swipeRefresh.setRefreshing(false);
StarredRepositoriesViewModel.loadStarredReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext(), pageSize, resultLimit);
@Override
public void onLoadMore() {
}, 50));
page += 1;
RepositoriesViewModel.loadMoreRepos(instanceToken, page, resultLimit, "", "starredRepos", null, getContext(), adapter);
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}
fetchDataAsync(((BaseActivity) requireActivity()).getAccount().getAuthorization(), pageSize, resultLimit);
@Override
public void onLoadFinished() {
return fragmentStarredRepositoriesBinding.getRoot();
}
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
}
});
private void fetchDataAsync(String instanceToken, int pageSize, int resultLimit) {
if(adapter.getItemCount() > 0) {
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataChanged();
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
}
StarredRepositoriesViewModel starredRepoModel = new ViewModelProvider(this).get(StarredRepositoriesViewModel.class);
starredRepoModel.getUserStarredRepositories(instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(),
starredReposListMain -> {
adapter = new ReposListAdapter(getContext(), starredReposListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
@ -132,11 +115,6 @@ public class StarredRepositoriesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
@ -146,7 +124,7 @@ public class StarredRepositoriesFragment extends Fragment {
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
if(fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
@ -160,7 +138,7 @@ public class StarredRepositoriesFragment extends Fragment {
super.onResume();
if(MainActivity.repoCreated) {
StarredRepositoriesViewModel.loadStarredReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), getContext(), pageSize, resultLimit);
RepositoriesViewModel.loadReposList(((BaseActivity) requireActivity()).getAccount().getAuthorization(), page, resultLimit, "", "starredRepos", null, getContext());
MainActivity.repoCreated = false;
}

View File

@ -14,7 +14,7 @@ import java.io.IOException;
import java.util.Objects;
/**
* Author M M Arif
* @author M M Arif
*/
public class ChangeLog {
@ -22,7 +22,7 @@ public class ChangeLog {
static final private String TAG = "ChangeLog";
static final private String CHANGELOG_XML_NODE = "changelog";
private Activity changelogActivity;
private final Activity changelogActivity;
public ChangeLog(Activity context) {
changelogActivity = context;

View File

@ -7,79 +7,86 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.AdminGetUsersAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Toasty;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
* @author M M Arif
*/
public class AdminGetUsersViewModel extends ViewModel {
private static MutableLiveData<List<UserInfo>> usersList;
public LiveData<List<UserInfo>> getUsersList(Context ctx, String token) {
public LiveData<List<UserInfo>> getUsersList(String token, int page, int resultLimit, Context ctx) {
usersList = new MutableLiveData<>();
loadUsersList(ctx, token);
loadUsersList(token, page, resultLimit, ctx);
return usersList;
}
public static void loadUsersList(final Context ctx, String token) {
public static void loadUsersList(String token, int page, int resultLimit, Context ctx) {
Call<List<UserInfo>> call = RetrofitClient
.getApiInterface(ctx)
.adminGetUsers(token);
.adminGetUsers(token, page, resultLimit);
call.enqueue(new Callback<List<UserInfo>>() {
@Override
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if (response.code() == 200) {
usersList.postValue(response.body());
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.cancelButton),
ctx.getResources().getString(R.string.navLogout));
}
else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.error(ctx, ctx.getString(R.string.genericError));
Log.i("onResponse", String.valueOf(response.code()));
}
if (response.isSuccessful()) {
usersList.postValue(response.body());
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString());
Log.e("onFailure", t.toString());
}
});
}
public static void loadMoreUsersList(String token, int page, int resultLimit, Context ctx, AdminGetUsersAdapter adapter) {
Call<List<UserInfo>> call = RetrofitClient
.getApiInterface(ctx)
.adminGetUsers(token, page, resultLimit);
call.enqueue(new Callback<List<UserInfo>>() {
@Override
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if (response.isSuccessful()) {
List<UserInfo> list = usersList.getValue();
assert list != null;
assert response.body() != null;
if(response.body().size() != 0) {
list.addAll(response.body());
adapter.updateList(list);
}
else {
adapter.setMoreDataAvailable(false);
}
}
else {
Log.e("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -80,6 +80,7 @@ public class IssuesViewModel extends ViewModel {
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if (response.isSuccessful()) {
List<Issues> list = issuesList.getValue();
assert list != null;
assert response.body() != null;

View File

@ -1,63 +0,0 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class MyRepositoriesViewModel extends ViewModel {
private static MutableLiveData<List<UserRepositories>> myReposList;
public LiveData<List<UserRepositories>> getCurrentUserRepositories(String token, String username, Context ctx, int page, int limit) {
//if (myReposList == null) {
myReposList = new MutableLiveData<>();
loadMyReposList(token, username, ctx, page, limit);
//}
return myReposList;
}
public static void loadMyReposList(String token, String username, Context ctx, int page, int limit) {
Call<List<UserRepositories>> call = RetrofitClient
.getApiInterface(ctx)
.getCurrentUserRepositories(token, username, page, limit);
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
myReposList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -1,63 +0,0 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserOrganizations;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class OrganizationListViewModel extends ViewModel {
private static MutableLiveData<List<UserOrganizations>> orgsList;
public LiveData<List<UserOrganizations>> getUserOrgs(String token, Context ctx) {
//if (orgsList == null) {
orgsList = new MutableLiveData<>();
loadOrgsList(token, ctx);
//}
return orgsList;
}
public static void loadOrgsList(String token, Context ctx) {
Call<List<UserOrganizations>> call = RetrofitClient
.getApiInterface(ctx)
.getUserOrgs(token, 1, 50);
call.enqueue(new Callback<List<UserOrganizations>>() {
@Override
public void onResponse(@NonNull Call<List<UserOrganizations>> call, @NonNull Response<List<UserOrganizations>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
orgsList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserOrganizations>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -0,0 +1,95 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserOrganizations;
import org.mian.gitnex.adapters.OrganizationsListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* @author M M Arif
*/
public class OrganizationsViewModel extends ViewModel {
private static MutableLiveData<List<UserOrganizations>> orgList;
public LiveData<List<UserOrganizations>> getUserOrg(String token, int page, int resultLimit, Context ctx) {
orgList = new MutableLiveData<>();
loadOrgList(token, page, resultLimit, ctx);
return orgList;
}
public static void loadOrgList(String token, int page, int resultLimit, Context ctx) {
Call<List<UserOrganizations>> call = RetrofitClient
.getApiInterface(ctx)
.getUserOrgs(token, page, resultLimit);
call.enqueue(new Callback<List<UserOrganizations>>() {
@Override
public void onResponse(@NonNull Call<List<UserOrganizations>> call, @NonNull Response<List<UserOrganizations>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
orgList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserOrganizations>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public static void loadMoreOrgList(String token, int page, int resultLimit, Context ctx, OrganizationsListAdapter adapter) {
Call<List<UserOrganizations>> call = RetrofitClient
.getApiInterface(ctx)
.getUserOrgs(token, page, resultLimit);
call.enqueue(new Callback<List<UserOrganizations>>() {
@Override
public void onResponse(@NonNull Call<List<UserOrganizations>> call, @NonNull Response<List<UserOrganizations>> response) {
if(response.isSuccessful()) {
List<UserOrganizations> list = orgList.getValue();
assert list != null;
assert response.body() != null;
if(response.body().size() != 0) {
list.addAll(response.body());
adapter.updateList(list);
}
else {
adapter.setMoreDataAvailable(false);
}
}
else {
Log.e("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<UserOrganizations>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -41,12 +41,8 @@ public class RepoStargazersViewModel extends ViewModel {
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
stargazersList.postValue(response.body());
}
stargazersList.postValue(response.body());
}
}
@Override
@ -55,6 +51,5 @@ public class RepoStargazersViewModel extends ViewModel {
}
});
}
}

View File

@ -41,20 +41,14 @@ public class RepoWatchersViewModel extends ViewModel {
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
watchersList.postValue(response.body());
}
watchersList.postValue(response.body());
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -1,61 +0,0 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class RepositoriesByOrgViewModel extends ViewModel {
private static MutableLiveData<List<UserRepositories>> orgReposList;
public LiveData<List<UserRepositories>> getRepositoriesByOrg(String token, String orgName, Context ctx, int page, int limit) {
orgReposList = new MutableLiveData<>();
loadOrgRepos(token, orgName, ctx, page, limit);
return orgReposList;
}
public static void loadOrgRepos(String token, String orgName, Context ctx, int page, int limit) {
Call<List<UserRepositories>> call = RetrofitClient
.getApiInterface(ctx)
.getReposByOrg(token, orgName, page, limit);
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
orgReposList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -1,63 +0,0 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class RepositoriesListViewModel extends ViewModel {
private static MutableLiveData<List<UserRepositories>> reposList;
public LiveData<List<UserRepositories>> getUserRepositories(String token, Context ctx, int page, int limit) {
//if (reposList == null) {
reposList = new MutableLiveData<>();
loadReposList(token, ctx, page, limit);
//}
return reposList;
}
public static void loadReposList(String token, Context ctx, int page, int limit) {
Call<List<UserRepositories>> call = RetrofitClient
.getApiInterface(ctx)
.getUserRepositories(token, page, limit);
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
reposList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -0,0 +1,121 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* @author M M Arif
*/
public class RepositoriesViewModel extends ViewModel {
private static MutableLiveData<List<UserRepositories>> reposList;
public LiveData<List<UserRepositories>> getRepositories(String token, int page, int resultLimit, String userLogin, String type, String orgName, Context ctx) {
reposList = new MutableLiveData<>();
loadReposList(token, page, resultLimit, userLogin, type, orgName, ctx);
return reposList;
}
public static void loadReposList(String token, int page, int resultLimit, String userLogin, String type, String orgName, Context ctx) {
Call<List<UserRepositories>> call;
switch(type) {
case "starredRepos":
call = RetrofitClient.getApiInterface(ctx).getUserStarredRepos(token, page, resultLimit);
break;
case "myRepos":
call = RetrofitClient.getApiInterface(ctx).getCurrentUserRepositories(token, userLogin, page, resultLimit);
break;
case "org":
call = RetrofitClient.getApiInterface(ctx).getReposByOrg(token, orgName, page, resultLimit);
break;
default:
call = RetrofitClient.getApiInterface(ctx).getUserRepositories(token, page, resultLimit);
break;
}
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
reposList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public static void loadMoreRepos(String token, int page, int resultLimit, String userLogin, String type, String orgName, Context ctx, ReposListAdapter adapter) {
Call<List<UserRepositories>> call;
switch(type) {
case "starredRepos":
call = RetrofitClient.getApiInterface(ctx).getUserStarredRepos(token, page, resultLimit);
break;
case "myRepos":
call = RetrofitClient.getApiInterface(ctx).getCurrentUserRepositories(token, userLogin, page, resultLimit);
break;
case "org":
call = RetrofitClient.getApiInterface(ctx).getReposByOrg(token, orgName, page, resultLimit);
break;
default:
call = RetrofitClient.getApiInterface(ctx).getUserRepositories(token, page, resultLimit);
break;
}
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
List<UserRepositories> list = reposList.getValue();
assert list != null;
assert response.body() != null;
if(response.body().size() != 0) {
list.addAll(response.body());
adapter.updateList(list);
}
else {
adapter.setMoreDataAvailable(false);
}
}
else {
Log.e("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -1,61 +0,0 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.clients.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class StarredRepositoriesViewModel extends ViewModel {
private static MutableLiveData<List<UserRepositories>> reposList;
public LiveData<List<UserRepositories>> getUserStarredRepositories(String token, Context ctx, int page, int limit) {
reposList = new MutableLiveData<>();
loadStarredReposList(token, ctx, page, limit);
return reposList;
}
public static void loadStarredReposList(String token, Context ctx, int page, int limit) {
Call<List<UserRepositories>> call = RetrofitClient
.getApiInterface(ctx)
.getUserStarredRepos(token, page, limit);
call.enqueue(new Callback<List<UserRepositories>>() {
@Override
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
reposList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserRepositories>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -46,10 +46,7 @@ public class TeamsByOrgViewModel extends ViewModel {
public void onResponse(@NonNull Call<List<Teams>> call, @NonNull Response<List<Teams>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
teamsList.postValue(response.body());
}
teamsList.postValue(response.body());
}
else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
@ -60,7 +57,6 @@ public class TeamsByOrgViewModel extends ViewModel {
mProgressBar.setVisibility(View.GONE);
noDataTeams.setText(R.string.genericError);
}
}
@Override
@ -69,9 +65,6 @@ public class TeamsByOrgViewModel extends ViewModel {
mProgressBar.setVisibility(View.GONE);
noDataTeams.setText(R.string.genericError);
}
});
}
}

View File

@ -1,49 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="208.41539"
android:viewportHeight="208.41539">
<group android:translateX="36.47269"
android:translateY="36.47269">
<path
android:pathData="M68.02,66.305m-94.784,-6.397a94.999,94.999 48.861,1 1,189.567 12.793a94.999,94.999 48.861,1 1,-189.567 -12.793"
android:strokeWidth="1.40255427"
android:fillColor="#39404a"/>
<path
android:pathData="M31.738,45.193a9.139,9.151 63.873,1 0,12.769 -13.108a9.139,9.151 63.873,1 0,-12.769 13.108z"
android:strokeWidth="0.99999666"
android:fillColor="#609926"/>
<path
android:pathData="M31.875,115.115a9.139,9.151 63.873,1 0,12.769 -13.108a9.139,9.151 63.873,1 0,-12.769 13.108z"
android:strokeWidth="0.99999666"
android:fillColor="#609926"/>
<path
android:pathData="M61.361,80.42a9.139,9.151 63.873,1 0,12.769 -13.108a9.139,9.151 63.873,1 0,-12.769 13.108z"
android:strokeWidth="0.99999666"
android:fillColor="#609926"/>
<path
android:pathData="M34.37,18.911l7.038,0.003l-0.096,85.655l-7.038,-0.003z"
android:fillColor="#609926"/>
<path
android:pathData="m37.878,38.707c31.743,0.128 29.614,-4.427 29.723,36.496"
android:strokeWidth="8.72550011"
android:fillColor="#00000000"
android:strokeColor="#609926"/>
<path
android:pathData="m97.323,109.027c-31.743,-0.128 -29.614,4.427 -29.723,-36.496"
android:strokeWidth="8.72550011"
android:fillColor="#00000000"
android:strokeColor="#609926"/>
<path
android:pathData="M90.959,45.193a9.139,9.151 63.873,1 0,12.769 -13.108a9.139,9.151 63.873,1 0,-12.769 13.108z"
android:strokeWidth="0.99999666"
android:fillColor="#609926"/>
<path
android:pathData="M90.955,115.117a9.139,9.151 63.873,1 0,12.769 -13.108a9.139,9.151 63.873,1 0,-12.769 13.108z"
android:strokeWidth="0.99999666"
android:fillColor="#609926"/>
<path
android:pathData="M93.872,35.636l7.038,0.002l-0.096,68.927l-7.038,-0.002z"
android:fillColor="#609926"/>
</group>
</vector>

View File

@ -1,27 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M21,8l0,13l-18,0l0,-13"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M1,3h22v5h-22z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M10,12L14,12"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/primaryBackgroundColor"
android:fitsSystemWindows="true"
android:orientation="vertical">
android:orientation="vertical"
android:background="?attr/primaryBackgroundColor">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
@ -40,20 +39,24 @@
android:layout_gravity="center_vertical"
android:text="@string/adminUsers"
android:textColor="?attr/primaryTextColor"
android:maxLines="1"
android:textSize="20sp" />
android:ellipsize="none"
android:scrollbars="horizontal"
android:singleLine="true"
android:layout_marginEnd="20dp"
android:textSize="18sp" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_marginTop="56dp"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
@ -61,8 +64,17 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="56dp"
android:indeterminate="true"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noDataUsers"
android:id="@+id/no_data_users"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
@ -70,6 +82,6 @@
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:textSize="20sp"
android:visibility="visible" />
android:visibility="gone" />
</LinearLayout>
</RelativeLayout>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noDataMyRepo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:gravity="center"
android:textSize="18sp"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/addNewRepo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:text="@string/pageTitleNewRepo"
android:contentDescription="@string/pageTitleNewRepo"
android:textColor="@color/colorWhite"
android:backgroundTint="?attr/fabColor"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:iconTint="@color/colorWhite"
app:icon="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.OrganizationDetailActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:textSize="18sp"
android:visibility="gone" />
</RelativeLayout>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:textSize="18sp"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/addNewRepo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:text="@string/pageTitleNewRepo"
android:contentDescription="@string/pageTitleNewRepo"
android:textColor="@color/colorWhite"
android:backgroundTint="?attr/fabColor"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:iconTint="@color/colorWhite"
app:icon="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingTop="10dp"
android:paddingRight="15dp"
android:paddingBottom="10dp">
<ImageView
android:id="@+id/commiter_avatar"
android:layout_width="35dp"
android:layout_height="35dp"
android:contentDescription="@string/generalImgContentText"
tools:srcCompat="@tools:sample/avatars" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:orientation="vertical">
<TextView
android:id="@+id/commit_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:textColor="?attr/primaryTextColor"
android:textStyle="bold"
tools:text="Voluptatem vero ad quia voluptatum quisquam. Nihil earum et praesentium." />
<TextView
android:id="@+id/commit_sha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
app:drawableStartCompat="@drawable/ic_commit"
app:drawableTint="?attr/primaryTextColor"
tools:text="afcfb7c15a" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View File

@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="?attr/primaryBackgroundColor" >
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:id="@+id/userInfoSection"

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:singleLine="true"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:background="?attr/primaryBackgroundColor"
android:textColor="?attr/primaryTextColor"/>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="16sp"
android:textColor="?attr/colorPrimary" />

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/replyToIssueMenu"
android:icon="@drawable/ic_drafts"
android:title="@string/titleDrafts"
android:orderInCategory="1"
app:showAsAction="ifRoom" />
</menu>