diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7d8d6002..2d24b0d0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -136,6 +136,9 @@
+
diff --git a/app/src/main/java/org/mian/gitnex/actions/TeamActions.java b/app/src/main/java/org/mian/gitnex/actions/TeamActions.java
index e74ad1f6..efdaf7ef 100644
--- a/app/src/main/java/org/mian/gitnex/actions/TeamActions.java
+++ b/app/src/main/java/org/mian/gitnex/actions/TeamActions.java
@@ -4,7 +4,9 @@ import android.content.Context;
import androidx.annotation.NonNull;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AddNewTeamMemberActivity;
+import org.mian.gitnex.activities.AddNewTeamRepoActivity;
import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.fragments.OrganizationTeamInfoReposFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call;
@@ -110,4 +112,101 @@ public class TeamActions {
}
});
}
+
+ public static void removeTeamRepo(final Context context, String orgName, int teamId, String repo) {
+
+ Call call = RetrofitClient
+ .getApiInterface(context)
+ .orgRemoveTeamRepository((long) teamId, orgName, repo);
+
+ call.enqueue(new Callback<>() {
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ if(response.isSuccessful()) {
+
+ if(response.code() == 204) {
+
+ OrganizationTeamInfoReposFragment.repoAdded = true;
+ Toasty.success(context, context.getString(R.string.repoRemovedMessage));
+ ((AddNewTeamRepoActivity) context).finish();
+ }
+
+ }
+ else if(response.code() == 401) {
+
+ AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ context.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.cancelButton),
+ context.getResources().getString(R.string.navLogout));
+ }
+ else if(response.code() == 403) {
+
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ }
+ else if(response.code() == 404) {
+
+ Toasty.warning(context, context.getString(R.string.apiNotFound));
+ }
+ else {
+
+ Toasty.error(context, context.getString(R.string.genericError));
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+
+ Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
+ }
+ });
+ }
+
+ public static void addTeamRepo(final Context context, String orgName, int teamId, String repo) {
+
+ Call call = RetrofitClient
+ .getApiInterface(context)
+ .orgAddTeamRepository((long) teamId, orgName, repo);
+
+ call.enqueue(new Callback<>() {
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ if(response.isSuccessful()) {
+
+ if(response.code() == 204) {
+
+ OrganizationTeamInfoReposFragment.repoAdded = true;
+ Toasty.success(context, context.getString(R.string.repoAddedMessage));
+ ((AddNewTeamRepoActivity) context).finish();
+ }
+ }
+ else if(response.code() == 401) {
+
+ AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ context.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.cancelButton),
+ context.getResources().getString(R.string.navLogout));
+ }
+ else if(response.code() == 403) {
+
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ }
+ else if(response.code() == 404) {
+
+ Toasty.warning(context, context.getString(R.string.apiNotFound));
+ }
+ else {
+
+ Toasty.error(context, context.getString(R.string.genericError));
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+
+ Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
+ }
+ });
+ }
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/AddNewTeamRepoActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddNewTeamRepoActivity.java
new file mode 100644
index 00000000..6c94222c
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/activities/AddNewTeamRepoActivity.java
@@ -0,0 +1,108 @@
+package org.mian.gitnex.activities;
+
+import android.os.Bundle;
+import android.view.View;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.v2.models.Repository;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.TeamRepositoriesAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.AddNewTeamRepositoryBinding;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.Toasty;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class AddNewTeamRepoActivity extends BaseActivity {
+
+ private AddNewTeamRepositoryBinding addNewTeamRepositoryBinding;
+ private View.OnClickListener onClickListener;
+ private List dataList;
+ private TeamRepositoriesAdapter adapter;
+ private int resultLimit;
+
+ private long teamId;
+ private String teamName;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+
+ addNewTeamRepositoryBinding = AddNewTeamRepositoryBinding.inflate(getLayoutInflater());
+ setContentView(addNewTeamRepositoryBinding.getRoot());
+
+ resultLimit = Constants.getCurrentResultLimit(ctx);
+ initCloseListener();
+ addNewTeamRepositoryBinding.close.setOnClickListener(onClickListener);
+
+ teamId = getIntent().getLongExtra("teamId", 0);
+ teamName = getIntent().getStringExtra("teamName");
+
+ addNewTeamRepositoryBinding.recyclerViewTeamRepos.setHasFixedSize(true);
+ addNewTeamRepositoryBinding.recyclerViewTeamRepos.setLayoutManager(new LinearLayoutManager(ctx));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(addNewTeamRepositoryBinding.recyclerViewTeamRepos.getContext(), DividerItemDecoration.VERTICAL);
+ addNewTeamRepositoryBinding.recyclerViewTeamRepos.addItemDecoration(dividerItemDecoration);
+
+ dataList = new ArrayList<>();
+
+ loadRepos();
+ }
+
+ public void loadRepos() {
+
+ Call> call = RetrofitClient.getApiInterface(ctx).orgListRepos(getIntent().getStringExtra("orgName"), 1, resultLimit);
+
+ addNewTeamRepositoryBinding.progressBar.setVisibility(View.VISIBLE);
+
+ call.enqueue(new Callback<>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+
+ dataList.clear();
+ dataList.addAll(response.body());
+
+ adapter = new TeamRepositoriesAdapter(dataList, ctx, Math.toIntExact(teamId), getIntent().getStringExtra("orgName"), teamName);
+
+ addNewTeamRepositoryBinding.recyclerViewTeamRepos.setAdapter(adapter);
+ addNewTeamRepositoryBinding.noData.setVisibility(View.GONE);
+ }
+ else {
+
+ addNewTeamRepositoryBinding.noData.setVisibility(View.VISIBLE);
+ }
+
+ addNewTeamRepositoryBinding.progressBar.setVisibility(View.GONE);
+ }
+ else {
+ Toasty.error(ctx, getString(R.string.genericError));
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
+ }
+ });
+ }
+
+ private void initCloseListener() {
+ onClickListener = view -> finish();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java
index dff14156..8b47f68d 100644
--- a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java
@@ -48,6 +48,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
private ContentsResponse file;
private RepositoryContext repository;
private boolean renderMd = false;
+ private boolean processable = false;
public ActivityResultLauncher editFileLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
@@ -108,8 +109,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
runOnUiThread(() -> binding.progressBar.setVisibility(View.GONE));
String fileExtension = FilenameUtils.getExtension(filename);
- boolean processable = false;
-
switch(AppUtil.getFileType(fileExtension)) {
case IMAGE:
@@ -246,7 +245,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
} else if(id == R.id.genericMenu) {
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
- bottomSheet.setArguments(repository.getBundle());
+ Bundle opts = repository.getBundle();
+ opts.putBoolean("editable", processable);
+ bottomSheet.setArguments(opts);
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
return true;
diff --git a/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java
index 255b1a12..d257a4f4 100644
--- a/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java
@@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import org.gitnex.tea4j.v2.models.OrganizationPermissions;
+import org.jetbrains.annotations.NotNull;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetOrganizationFragment;
@@ -40,6 +41,8 @@ import retrofit2.Response;
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetListener {
public OrganizationPermissions permissions;
+ private String orgName;
+ private boolean isMember = false;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -48,89 +51,118 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
setContentView(R.layout.activity_org_detail);
- String orgName = getIntent().getStringExtra("orgName");
+ orgName = getIntent().getStringExtra("orgName");
Toolbar toolbar = findViewById(R.id.toolbar);
- TextView toolbarTitle = findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- OrganizationDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrganizationDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
-
- ViewPager mViewPager = findViewById(R.id.container);
- mViewPager.setAdapter(mSectionsPagerAdapter);
-
- TabLayout tabLayout = findViewById(R.id.tabs);
-
- Typeface myTypeface;
-
- switch(tinyDB.getInt("customFontId", -1)) {
-
- case 0:
-
- myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
- break;
- case 2:
-
- myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
- break;
- default:
-
- myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
- break;
- }
-
- toolbarTitle.setTypeface(myTypeface);
- toolbarTitle.setText(orgName);
-
- ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
- int tabsCount = vg.getChildCount();
-
- for (int j = 0; j < tabsCount; j++) {
-
- ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
- int tabChildCount = vgTab.getChildCount();
-
- for (int i = 0; i < tabChildCount; i++) {
-
- View tabViewChild = vgTab.getChildAt(i);
-
- if (tabViewChild instanceof TextView) {
-
- ((TextView) tabViewChild).setTypeface(myTypeface);
- }
- }
- }
-
- mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
- tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
+ checkIsMember();
if(getAccount().requiresVersion("1.16.0")) {
RetrofitClient.getApiInterface(this)
- .orgGetUserPermissions(getAccount().getAccount().getUserName(), orgName).enqueue(new Callback() {
+ .orgGetUserPermissions(getAccount().getAccount().getUserName(), orgName).enqueue(new Callback<>() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) {
- if(response.isSuccessful()) {
- permissions = response.body();
- }
- else {
- permissions = null;
- }
- }
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
- @Override
- public void onFailure(@NonNull Call call, @NonNull Throwable t) {
- permissions = null;
- }
- });
+ if(response.isSuccessful()) {
+ permissions = response.body();
+ }
+ else {
+ permissions = null;
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+
+ permissions = null;
+ }
+ });
} else {
permissions = null;
}
}
+ public void checkIsMember() {
+ RetrofitClient.getApiInterface(this).orgIsMember(orgName, getAccount().getAccount().getUserName()).enqueue(new Callback<>() {
+
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) {
+ isMember = response.code() != 404;
+ init();
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull Throwable t) {
+ isMember = false;
+ init();
+ }
+ });
+ }
+
+ public void init() {
+ OrganizationDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrganizationDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
+
+ ViewPager mViewPager = findViewById(R.id.container);
+ mViewPager.setVisibility(View.VISIBLE);
+ mViewPager.setAdapter(mSectionsPagerAdapter);
+
+ TabLayout tabLayout = findViewById(R.id.tabs);
+ tabLayout.setVisibility(View.VISIBLE);
+
+ if(!isMember) {
+ tabLayout.removeTabAt(3);
+ }
+
+ Typeface myTypeface;
+
+ switch(tinyDB.getInt("customFontId", -1)) {
+
+ case 0:
+
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
+ break;
+ case 2:
+
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
+ break;
+ default:
+
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
+ break;
+ }
+
+ TextView toolbarTitle = findViewById(R.id.toolbar_title);
+
+ toolbarTitle.setTypeface(myTypeface);
+ toolbarTitle.setText(orgName);
+
+ ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
+ int tabsCount = vg.getChildCount();
+
+ for (int j = 0; j < tabsCount; j++) {
+
+ ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
+ int tabChildCount = vgTab.getChildCount();
+
+ for (int i = 0; i < tabChildCount; i++) {
+
+ View tabViewChild = vgTab.getChildAt(i);
+
+ if (tabViewChild instanceof TextView) {
+
+ ((TextView) tabViewChild).setTypeface(myTypeface);
+ }
+ }
+ }
+
+ mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
+ tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
+ }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
@@ -226,19 +258,29 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
case 2: // labels
return OrganizationLabelsFragment.newInstance(orgName);
- case 3: // teams
+ case 3: // teams / members
- return TeamsByOrgFragment.newInstance(orgName, permissions);
+ if(isMember) {
+ return TeamsByOrgFragment.newInstance(orgName, permissions);
+ } else {
+ return MembersByOrgFragment.newInstance(orgName);
+ }
case 4: // members
- return MembersByOrgFragment.newInstance(orgName);
+ if(isMember) {
+ return MembersByOrgFragment.newInstance(orgName);
+ }
}
return fragment;
}
@Override
public int getCount() {
- return 5;
+ if(isMember) {
+ return 5;
+ } else {
+ return 4;
+ }
}
}
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamInfoActivity.java b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamInfoActivity.java
index a9b7541c..2e87111a 100644
--- a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamInfoActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamInfoActivity.java
@@ -19,6 +19,7 @@ import org.mian.gitnex.databinding.ActivityOrgTeamInfoBinding;
import org.mian.gitnex.fragments.BottomSheetOrganizationTeamsFragment;
import org.mian.gitnex.fragments.OrganizationTeamInfoMembersFragment;
import org.mian.gitnex.fragments.OrganizationTeamInfoPermissionsFragment;
+import org.mian.gitnex.fragments.OrganizationTeamInfoReposFragment;
import org.mian.gitnex.structs.BottomSheetListener;
/**
@@ -50,14 +51,17 @@ public class OrganizationTeamInfoActivity extends BaseActivity implements Bottom
}
binding.close.setOnClickListener(view -> finish());
+ binding.pager.setOffscreenPageLimit(1);
binding.pager.setAdapter(new FragmentStateAdapter(getSupportFragmentManager(), getLifecycle()) {
@NonNull
@Override
public Fragment createFragment(int position) {
switch(position) {
case 0:
- return OrganizationTeamInfoMembersFragment.newInstance(team);
+ return OrganizationTeamInfoReposFragment.newInstance(team);
case 1:
+ return OrganizationTeamInfoMembersFragment.newInstance(team);
+ case 2:
return OrganizationTeamInfoPermissionsFragment.newInstance(team);
}
return null;
@@ -65,20 +69,23 @@ public class OrganizationTeamInfoActivity extends BaseActivity implements Bottom
@Override
public int getItemCount() {
- return 2;
+ return 3;
}
});
new TabLayoutMediator(binding.tabs, binding.pager, (tab, position) -> {
- TextView textView = (TextView) LayoutInflater.from(ctx).inflate(R.layout.layout_tab_text, null);
+ TextView textView = (TextView) LayoutInflater.from(ctx).inflate(R.layout.layout_tab_text, findViewById(android.R.id.content), false);
switch(position) {
case 0:
- textView.setText(R.string.orgTabMembers);
+ textView.setText(R.string.navRepos);
break;
case 1:
- textView.setText(R.string.teamPermissions);
+ textView.setText(R.string.orgTabMembers);
break;
+ case 2:
+ textView.setText(R.string.teamPermissions);
+ break;
}
tab.setCustomView(textView);
@@ -105,6 +112,9 @@ public class OrganizationTeamInfoActivity extends BaseActivity implements Bottom
}
else if(id == R.id.genericMenu) {
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
+ Bundle args = new Bundle();
+ args.putBoolean("showRepo", !team.isIncludesAllRepositories());
+ bottomSheet.setArguments(args);
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
return true;
}
@@ -119,6 +129,12 @@ public class OrganizationTeamInfoActivity extends BaseActivity implements Bottom
Intent intent = new Intent(OrganizationTeamInfoActivity.this, AddNewTeamMemberActivity.class);
intent.putExtra("teamId", team.getId());
startActivity(intent);
+ } else if("newRepo".equals(text)) {
+ Intent intent = new Intent(OrganizationTeamInfoActivity.this, AddNewTeamRepoActivity.class);
+ intent.putExtra("teamId", team.getId());
+ intent.putExtra("teamName", team.getName());
+ intent.putExtra("orgName", getIntent().getStringExtra("orgName"));
+ startActivity(intent);
}
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/TeamRepositoriesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/TeamRepositoriesAdapter.java
new file mode 100644
index 00000000..172886e3
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/TeamRepositoriesAdapter.java
@@ -0,0 +1,157 @@
+package org.mian.gitnex.adapters;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import com.amulyakhare.textdrawable.TextDrawable;
+import com.amulyakhare.textdrawable.util.ColorGenerator;
+import org.gitnex.tea4j.v2.models.Repository;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class TeamRepositoriesAdapter extends RecyclerView.Adapter {
+
+ private final List reposList;
+ private final Context context;
+ private final int teamId;
+ private final String orgName;
+ private final String teamName;
+ private final List reposArr;
+
+ public TeamRepositoriesAdapter(List dataList, Context ctx, int teamId, String orgName, String teamName) {
+ this.context = ctx;
+ this.reposList = dataList;
+ this.teamId = teamId;
+ this.orgName = orgName;
+ this.teamName = teamName;
+ reposArr = new ArrayList<>();
+ }
+
+ class TeamReposViewHolder extends RecyclerView.ViewHolder {
+
+ private Repository repoInfo;
+
+ private final ImageView repoAvatar;
+ private final TextView name;
+ private final ImageView addRepoButtonAdd;
+
+ private TeamReposViewHolder(View itemView) {
+
+ super(itemView);
+ repoAvatar = itemView.findViewById(R.id.userAvatar);
+ name = itemView.findViewById(R.id.userFullName);
+ itemView.findViewById(R.id.userName).setVisibility(View.GONE);
+ addRepoButtonAdd = itemView.findViewById(R.id.addCollaboratorButtonAdd);
+ ImageView addRepoButtonRemove = itemView.findViewById(R.id.addCollaboratorButtonRemove);
+ //addRepoButtonAdd.setVisibility(View.VISIBLE);
+ //addRepoButtonRemove.setVisibility(View.GONE);
+
+ new Handler(Looper.getMainLooper()).postDelayed(TeamRepositoriesAdapter.this::getTeamRepos, 200);
+
+ new Handler(Looper.getMainLooper()).postDelayed(() -> {
+
+ if(reposArr.size() > 0) {
+ for(int i = 0; i < reposArr.size(); i++) {
+ if(!reposArr.get(i).getName().equals(repoInfo.getName())) {
+ addRepoButtonAdd.setVisibility(View.VISIBLE);
+ }
+ else {
+ addRepoButtonAdd.setVisibility(View.GONE);
+ }
+ }
+ }
+ else {
+ addRepoButtonAdd.setVisibility(View.VISIBLE);
+ }
+ }, 500);
+
+ addRepoButtonAdd.setOnClickListener(v -> AlertDialogs.addRepoDialog(context, orgName, repoInfo.getName(), Integer.parseInt(String.valueOf(teamId)), teamName));
+
+ addRepoButtonRemove.setOnClickListener(v ->
+ AlertDialogs.removeRepoDialog(context, orgName, repoInfo.getName(), Integer.parseInt(String.valueOf(teamId)), teamName));
+ }
+
+ }
+
+ @NonNull
+ @Override
+ public TeamRepositoriesAdapter.TeamReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_collaborators_search, parent, false);
+ return new TeamRepositoriesAdapter.TeamReposViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final TeamRepositoriesAdapter.TeamReposViewHolder holder, int position) {
+
+ Repository currentItem = reposList.get(position);
+ holder.repoInfo = currentItem;
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ holder.name.setText(currentItem.getName());
+
+ TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28)
+ .endConfig().buildRoundRect(String.valueOf(currentItem.getFullName().charAt(0)), ColorGenerator.Companion.getMATERIAL().getColor(currentItem.getName()), 3);
+
+ if(currentItem.getAvatarUrl() != null && !currentItem.getAvatarUrl().equals("")) {
+ PicassoService.getInstance(context).get().load(currentItem.getAvatarUrl()).placeholder(R.drawable.loader_animated)
+ .transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.repoAvatar);
+ }
+ else {
+ holder.repoAvatar.setImageDrawable(drawable);
+ }
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return reposList.size();
+ }
+
+ private void getTeamRepos() {
+
+ if(getItemCount() > 0) {
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .orgListTeamRepos((long) teamId, 1, 50);
+
+ call.enqueue(new Callback<>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.code() == 200) {
+
+ for(int i = 0; i < Objects.requireNonNull(response.body()).size(); i++) {
+ reposArr.addAll(response.body());
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetFileViewerFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetFileViewerFragment.java
index 99fd42e0..390228b2 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetFileViewerFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetFileViewerFragment.java
@@ -30,6 +30,8 @@ public class BottomSheetFileViewerFragment extends BottomSheetDialogFragment {
if(!repository.getPermissions().isPush()) {
bottomSheetFileViewerBinding.deleteFile.setVisibility(View.GONE);
bottomSheetFileViewerBinding.editFile.setVisibility(View.GONE);
+ } else if(!requireArguments().getBoolean("editable")) {
+ bottomSheetFileViewerBinding.editFile.setVisibility(View.GONE);
}
bottomSheetFileViewerBinding.downloadFile.setOnClickListener(v1 -> {
diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationTeamsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationTeamsFragment.java
index cc74434a..1748a4d5 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationTeamsFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationTeamsFragment.java
@@ -33,6 +33,15 @@ public class BottomSheetOrganizationTeamsFragment extends BottomSheetDialogFragm
});
+ if(!requireArguments().getBoolean("showRepo")) {
+ bottomSheetOrganizationTeamsBinding.addRepo.setVisibility(View.GONE);
+ }
+ bottomSheetOrganizationTeamsBinding.addRepo.setOnClickListener(v1 -> {
+ bmListener.onButtonClicked("newRepo");
+ dismiss();
+
+ });
+
return bottomSheetOrganizationTeamsBinding.getRoot();
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java
index 6f81d1b0..21445715 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java
@@ -251,6 +251,10 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
binding.bottomSheetHeaderFrame.setVisibility(View.GONE);
binding.issuePrDivider.setVisibility(View.GONE);
}
+ else if(!canPush) {
+ binding.addRemoveAssignees.setVisibility(View.GONE);
+ binding.editLabels.setVisibility(View.GONE);
+ }
return binding.getRoot();
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/OrganizationTeamInfoReposFragment.java b/app/src/main/java/org/mian/gitnex/fragments/OrganizationTeamInfoReposFragment.java
new file mode 100644
index 00000000..5611800f
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/OrganizationTeamInfoReposFragment.java
@@ -0,0 +1,159 @@
+package org.mian.gitnex.fragments;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import org.gitnex.tea4j.v2.models.Team;
+import org.mian.gitnex.R;
+import org.mian.gitnex.activities.MainActivity;
+import org.mian.gitnex.adapters.ReposListAdapter;
+import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.DividerItemDecorator;
+import org.mian.gitnex.viewmodels.RepositoriesViewModel;
+
+/**
+ * @author M M Arif
+ */
+
+public class OrganizationTeamInfoReposFragment extends Fragment {
+
+ private RepositoriesViewModel repositoriesViewModel;
+ public static boolean repoAdded = false;
+
+ private FragmentRepositoriesBinding fragmentRepositoriesBinding;
+ private ReposListAdapter adapter;
+ private int page = 1;
+ private int resultLimit;
+
+ private Team team;
+
+ public static OrganizationTeamInfoReposFragment newInstance(Team team) {
+ OrganizationTeamInfoReposFragment fragment = new OrganizationTeamInfoReposFragment();
+
+ Bundle bundle = new Bundle();
+ bundle.putSerializable("team", team);
+ fragment.setArguments(bundle);
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
+
+ resultLimit = Constants.getCurrentResultLimit(getContext());
+ setHasOptionsMenu(true);
+ team = (Team) requireArguments().getSerializable("team");
+
+ repositoriesViewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
+
+ fragmentRepositoriesBinding.addNewRepo.setVisibility(View.GONE);
+
+ fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
+ fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+
+ RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecorator(ContextCompat.getDrawable(requireContext(), R.drawable.shape_list_divider));
+ fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+
+ fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+
+ page = 1;
+ fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
+ fetchDataAsync();
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
+ }, 50));
+
+ fetchDataAsync();
+
+ return fragmentRepositoriesBinding.getRoot();
+ }
+
+ private void fetchDataAsync() {
+
+ repositoriesViewModel.getRepositories(page, resultLimit, String.valueOf(team.getId()), "team", null, getContext()).observe(getViewLifecycleOwner(), reposListMain -> {
+
+ adapter = new ReposListAdapter(reposListMain, getContext());
+ adapter.setLoadMoreListener(new ReposListAdapter.OnLoadMoreListener() {
+
+ @Override
+ public void onLoadMore() {
+
+ page += 1;
+ repositoriesViewModel.loadMoreRepos(page, resultLimit, String.valueOf(team.getId()), "team", 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(repoAdded) {
+ page = 1;
+ fetchDataAsync();
+ MainActivity.repoCreated = false;
+ }
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ if(fragmentRepositoriesBinding.recyclerView.getAdapter() != null) {
+ adapter.getFilter().filter(newText);
+ }
+ return false;
+ }
+ });
+ }
+}
+
diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java
index 8486e8c3..f3722d65 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java
@@ -79,6 +79,7 @@ public class RepositoriesByOrgFragment extends Fragment {
fragmentRepositoriesBinding.progressBar.setVisibility(View.VISIBLE);
}, 50));
+ page = 1;
fetchDataAsync();
return fragmentRepositoriesBinding.getRoot();
diff --git a/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java b/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java
index 1823b63a..b5a2d7f6 100644
--- a/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java
+++ b/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java
@@ -105,6 +105,26 @@ public class AlertDialogs {
}
+ public static void addRepoDialog(final Context context, final String orgName, String repo, int teamId, String teamName) {
+
+ new AlertDialog.Builder(context)
+ .setTitle(context.getResources().getString(R.string.addTeamMemberTitle) + repo)
+ .setMessage(context.getResources().getString(R.string.repoAddToTeamMessage, repo, orgName, teamName))
+ .setPositiveButton(context.getResources().getString(R.string.addButton), (dialog, whichButton) -> TeamActions.addTeamRepo(context, orgName, teamId, repo))
+ .setNeutralButton(context.getResources().getString(R.string.cancelButton), null).show();
+
+ }
+
+ public static void removeRepoDialog(final Context context, final String orgName, String repo, int teamId, String teamName) {
+
+ new AlertDialog.Builder(context)
+ .setTitle(context.getResources().getString(R.string.removeTeamMemberTitle) + repo)
+ .setMessage(context.getResources().getString(R.string.repoRemoveTeamMessage, repo, teamName))
+ .setPositiveButton(context.getResources().getString(R.string.removeButton), (dialog, whichButton) -> TeamActions.removeTeamRepo(context, orgName, teamId, repo))
+ .setNeutralButton(context.getResources().getString(R.string.cancelButton), null).show();
+
+ }
+
public static void selectPullUpdateStrategy(Context context, String repoOwner, String repo, String issueNumber) {
Dialog dialog = new Dialog(context, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesViewModel.java
index 2e14b8cc..7d6bf805 100644
--- a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesViewModel.java
+++ b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesViewModel.java
@@ -45,6 +45,9 @@ public class RepositoriesViewModel extends ViewModel {
case "org":
call = RetrofitClient.getApiInterface(ctx).orgListRepos(orgName, page, resultLimit);
break;
+ case "team":
+ call = RetrofitClient.getApiInterface(ctx).orgListTeamRepos(Long.valueOf(userLogin), page, resultLimit);
+ break;
default:
call = RetrofitClient.getApiInterface(ctx).userCurrentListRepos(page, resultLimit);
break;
@@ -88,6 +91,9 @@ public class RepositoriesViewModel extends ViewModel {
case "org":
call = RetrofitClient.getApiInterface(ctx).orgListRepos(orgName, page, resultLimit);
break;
+ case "team":
+ call = RetrofitClient.getApiInterface(ctx).orgListTeamRepos(Long.valueOf(userLogin), page, resultLimit);
+ break;
default:
call = RetrofitClient.getApiInterface(ctx).userCurrentListRepos(page, resultLimit);
break;
diff --git a/app/src/main/res/layout/activity_org_detail.xml b/app/src/main/res/layout/activity_org_detail.xml
index 4c338d50..db7d7d61 100644
--- a/app/src/main/res/layout/activity_org_detail.xml
+++ b/app/src/main/res/layout/activity_org_detail.xml
@@ -43,7 +43,8 @@
android:background="?attr/primaryBackgroundColor"
app:tabIndicatorColor="?attr/pagerTabIndicatorColor"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ android:visibility="gone"/>
diff --git a/app/src/main/res/layout/add_new_team_repository.xml b/app/src/main/res/layout/add_new_team_repository.xml
new file mode 100644
index 00000000..5729a102
--- /dev/null
+++ b/app/src/main/res/layout/add_new_team_repository.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/bottom_sheet_organization_teams.xml b/app/src/main/res/layout/bottom_sheet_organization_teams.xml
index 3af67cc0..223f6c40 100644
--- a/app/src/main/res/layout/bottom_sheet_organization_teams.xml
+++ b/app/src/main/res/layout/bottom_sheet_organization_teams.xml
@@ -45,6 +45,19 @@
android:padding="8dp"
app:alignContent="stretch" >
+
+
Do you want to remove this user from the team?
Member added to the team successfully
Member removed from the team successfully
+ Repository added to the team successfully
+ Repository removed from the team successfully
+ Add repository %s to organization %s team %s
+ Remove repository %s from team %s