Add to admin users

This commit is contained in:
M M Arif
2022-03-17 14:39:38 +05:00
parent eb875de1ed
commit 24dc10c9aa
8 changed files with 269 additions and 200 deletions
+1 -1
View File
@@ -109,7 +109,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'
@@ -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;
import org.mian.gitnex.databinding.ActivityAdminGetUsersBinding;
/**
* 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();
}
}
@@ -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,116 +25,167 @@ 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 final int TYPE_LOAD = 0;
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);
if(viewType == TYPE_LOAD) {
return new AdminGetUsersAdapter.ReposHolder(inflater.inflate(R.layout.list_admin_users, parent, false));
}
else {
return new AdminGetUsersAdapter.LoadHolder(inflater.inflate(R.layout.row_load, 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) {
if(getItemViewType(position) == TYPE_LOAD) {
((AdminGetUsersAdapter.ReposHolder) holder).bindData(usersList.get(position));
}
}
super(itemView);
@Override
public int getItemViewType(int position) {
if(usersList.get(position).getFullname() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
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.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
private String userLoginId;
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userEmail;
private final ImageView userRole;
private final TextView userName;
public AdminGetUsersAdapter(Context ctx, List<UserInfo> usersListMain) {
ReposHolder(View itemView) {
this.context = ctx;
this.usersList = usersListMain;
usersListFull = new ArrayList<>(usersList);
}
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);
@NonNull
@Override
public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_admin_users, parent, false);
return new AdminGetUsersAdapter.UsersViewHolder(v);
}
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
@Override
public void onBindViewHolder(@NonNull AdminGetUsersAdapter.UsersViewHolder holder, int position) {
void bindData(UserInfo users) {
UserInfo currentItem = usersList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userLoginId = currentItem.getLogin();
userLoginId = users.getLogin();
if(!currentItem.getFullname().equals("")) {
if(!users.getFullname().equals("")) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
else {
userFullName.setText(Html.fromHtml(users.getFullname()));
userName.setText(context.getResources().getString(R.string.usernameWithAt, users.getUsername()));
}
else {
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setVisibility(View.GONE);
}
userFullName.setText(context.getResources().getString(R.string.usernameWithAt, users.getUsername()));
userName.setVisibility(View.GONE);
}
if(!currentItem.getEmail().equals("")) {
if(!users.getEmail().equals("")) {
userEmail.setText(users.getEmail());
}
else {
userEmail.setVisibility(View.GONE);
}
holder.userEmail.setText(currentItem.getEmail());
}
else {
if(users.getIs_admin()) {
holder.userEmail.setVisibility(View.GONE);
}
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 {
if(currentItem.getIs_admin()) {
userRole.setVisibility(View.GONE);
}
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 {
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.GONE);
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
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 void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if(!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
@Override
public int getItemCount() {
return usersList.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<UserInfo> list) {
usersList = list;
notifyDataChanged();
}
@Override
public Filter getFilter() {
@@ -169,8 +221,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
usersList.clear();
usersList.addAll((List) results.values);
notifyDataSetChanged();
notifyDataChanged();
}
};
}
@@ -92,7 +92,7 @@ public class RepositoriesFragment extends Fragment {
fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
}
});
Log.e("adapter.getItemCount()", String.valueOf(adapter.getItemCount()));
if(adapter.getItemCount() > 0) {
fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
@@ -7,79 +7,88 @@ 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()) {
if(response.code() == 200) {
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());
}
});
}
}
@@ -57,7 +57,6 @@ public class RepositoriesViewModel extends ViewModel {
if(response.isSuccessful()) {
if(response.code() == 200) {
reposList.postValue(response.body());
Log.e("typeRepo", String.valueOf(reposList));
}
}
}
@@ -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>
+1 -1
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"