diff --git a/app/build.gradle b/app/build.gradle index bc1bba83..3480e2d8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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.0.24" + implementation "org.codeberg.gitnex:tea4j:1.0.29" 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' diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java index 2718eca9..318a9adf 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java @@ -138,6 +138,13 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis viewBinding.createNewIssueButton.setOnClickListener(this); } + if(!tinyDB.getBoolean("canPush")) { + viewBinding.newIssueAssigneesListLayout.setVisibility(View.GONE); + viewBinding.newIssueMilestoneSpinnerLayout.setVisibility(View.GONE); + viewBinding.newIssueLabelsLayout.setVisibility(View.GONE); + viewBinding.newIssueDueDateLayout.setVisibility(View.GONE); + } + } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java index 5c7256ed..1b6ef4cf 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java @@ -112,6 +112,11 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis viewBinding.prLabels.setOnClickListener(prLabels -> showLabels()); viewBinding.createPr.setOnClickListener(createPr -> processPullRequest()); + + if(!tinyDB.getBoolean("canPush")) { + viewBinding.prDueDateLayout.setVisibility(View.GONE); + viewBinding.prLabelsLayout.setVisibility(View.GONE); + } } private void processPullRequest() { diff --git a/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java index aadaf622..4004fd23 100644 --- a/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java @@ -479,6 +479,7 @@ public class DeepLinksActivity extends BaseActivity { tinyDB.putString("repoType", getResources().getString(R.string.strPublic)); } tinyDB.putBoolean("isRepoAdmin", repoInfo.getPermissions().isAdmin()); + tinyDB.putBoolean("canPush", repoInfo.getPermissions().canPush()); tinyDB.putString("repoBranch", repoInfo.getDefault_branch()); int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId"); diff --git a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java index 2a039a9a..148d3a06 100644 --- a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java @@ -133,6 +133,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe disableProcessButton(); getIssue(instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); + + if(!tinyDB.getBoolean("canPush")) { + findViewById(R.id.editIssueMilestoneSpinnerLayout).setVisibility(View.GONE); + findViewById(R.id.editIssueDueDateLayout).setVisibility(View.GONE); + } } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java b/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java index a9019e08..fd951dd5 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java @@ -114,11 +114,17 @@ public class FileDiffActivity extends BaseActivity { break; case 403: - runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError))); + runOnUiThread(() -> { + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + finish(); + }); break; case 404: - runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound))); + runOnUiThread(() -> { + Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); + finish(); + }); break; default: diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java index dc937fbe..7c84b55c 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -33,7 +33,9 @@ import com.vdurmont.emoji.EmojiParser; import org.gitnex.tea4j.models.Collaborators; import org.gitnex.tea4j.models.Issues; import org.gitnex.tea4j.models.Labels; +import org.gitnex.tea4j.models.PullRequests; import org.gitnex.tea4j.models.UpdateIssueAssignees; +import org.gitnex.tea4j.models.UserRepositories; import org.gitnex.tea4j.models.WatchInfo; import org.mian.gitnex.R; import org.mian.gitnex.actions.AssigneesActions; @@ -86,6 +88,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt private String repoOwner; private String repoName; private int issueIndex; + private String issueCreator; private LabelsListAdapter labelsAdapter; private AssigneesListAdapter assigneesAdapter; @@ -450,7 +453,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt } else if(id == R.id.genericMenu) { - BottomSheetSingleIssueFragment bottomSheet = new BottomSheetSingleIssueFragment(); + BottomSheetSingleIssueFragment bottomSheet = new BottomSheetSingleIssueFragment(issueCreator); bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet"); return true; } @@ -542,6 +545,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt } private void getSingleIssue(String repoOwner, String repoName, int issueIndex) { + updateTinyDBPermissionValues(); final TinyDB tinyDb = TinyDB.getInstance(appCtx); Call call = RetrofitClient.getApiInterface(ctx) @@ -560,7 +564,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.issuePrState.setVisibility(View.VISIBLE); if(singleIssue.getPull_request() != null) { - + getPullSourceRepo(); if(singleIssue.getPull_request().isMerged()) { // merged viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request_merged); @@ -585,6 +589,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt tinyDb.putString("issueState", singleIssue.getState()); tinyDb.putString("issueTitle", singleIssue.getTitle()); tinyDb.putString("singleIssueHtmlUrl", singleIssue.getHtml_url()); + issueCreator = singleIssue.getUser().getLogin(); PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated) .transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewBinding.assigneeAvatar); @@ -864,4 +869,56 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt } + private void updateTinyDBPermissionValues() { + RetrofitClient.getApiInterface(this).getUserRepository(Authorization.get(this), repoOwner, repoName).enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if(response.isSuccessful()) { + assert response.body() != null; + tinyDB.putBoolean("isArchived", response.body().isArchived()); + if(response.body().isArchived()) { + viewBinding.addNewComment.setVisibility(View.GONE); + } + tinyDB.putBoolean("isRepoAdmin", response.body().getPermissions().isAdmin()); + tinyDB.putBoolean("canPush", response.body().getPermissions().canPush()); + } + else { + onFailure(call, new Throwable()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + tinyDB.putBoolean("isRepoAdmin", false); + tinyDB.putBoolean("canPush", false); + } + }); + } + + private void getPullSourceRepo() { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.15.4")) { + RetrofitClient.getApiInterface(this).getPullRequestByIndex(Authorization.get(this), repoOwner, repoName, issueIndex).enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if(response.isSuccessful() && response.body() != null) { + tinyDB.putBoolean("canPushPullSource", response.body().getHead().getRepo().getPermissions().isPush()); + } + else { + tinyDB.putBoolean("canPushPullSource", false); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + tinyDB.putBoolean("canPushPullSource", false); + } + }); + } + else { + tinyDB.putBoolean("canPushPullSource", true); + } + } + } diff --git a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java index 1a003291..4647f7d7 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java @@ -108,6 +108,11 @@ public class MergePullRequestActivity extends BaseActivity { viewBinding.mergeButton.setOnClickListener(mergePullRequest); } + if(!tinyDB.getBoolean("canPushPullSource")) { + viewBinding.deleteBranch.setVisibility(View.GONE); + viewBinding.deleteBranchForkInfo.setVisibility(View.GONE); + } + } private void setMergeAdapter() { 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 f84e62b2..64ee85ef 100644 --- a/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java @@ -19,17 +19,25 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; +import org.gitnex.tea4j.models.OrgPermissions; import org.mian.gitnex.R; +import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.fragments.BottomSheetOrganizationFragment; import org.mian.gitnex.fragments.MembersByOrgFragment; import org.mian.gitnex.fragments.OrganizationInfoFragment; import org.mian.gitnex.fragments.OrganizationLabelsFragment; import org.mian.gitnex.fragments.RepositoriesByOrgFragment; import org.mian.gitnex.fragments.TeamsByOrgFragment; +import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.structs.BottomSheetListener; +import org.mian.gitnex.helpers.Version; +import java.util.List; import java.util.Objects; import io.mikael.urlbuilder.UrlBuilder; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -37,6 +45,8 @@ import io.mikael.urlbuilder.UrlBuilder; public class OrganizationDetailActivity extends BaseActivity implements BottomSheetListener { + public OrgPermissions permissions; + @Override public void onCreate(Bundle savedInstanceState) { @@ -44,7 +54,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh setContentView(R.layout.activity_org_detail); - String orgName = tinyDB.getString("orgName"); + String orgName = tinyDB.getString("orgName"); Toolbar toolbar = findViewById(R.id.toolbar); TextView toolbarTitle = findViewById(R.id.toolbar_title); @@ -102,6 +112,29 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); + + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.16.0")) { + RetrofitClient.getApiInterface(this) + .getOrgPermissions(Authorization.get(this), tinyDB.getString("loginUid"), 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 onFailure(@NonNull Call call, @NonNull Throwable t) { + permissions = null; + } + }); + } else { + permissions = null; + } } @@ -125,7 +158,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh } else if(id == R.id.repoMenu) { - BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(); + BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(permissions); bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet"); return true; } @@ -203,7 +236,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh return OrganizationLabelsFragment.newInstance(orgName); case 3: // teams - return TeamsByOrgFragment.newInstance(orgName); + return TeamsByOrgFragment.newInstance(orgName, permissions); case 4: // members return MembersByOrgFragment.newInstance(orgName); diff --git a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java index 4fa15c77..3d18624f 100644 --- a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java @@ -12,6 +12,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.ViewModelProvider; +import org.gitnex.tea4j.models.OrgPermissions; import org.mian.gitnex.R; import org.mian.gitnex.adapters.UserGridAdapter; import org.mian.gitnex.databinding.ActivityOrgTeamMembersBinding; @@ -95,7 +96,7 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class); - teamMembersModel.getMembersByOrgList(instanceToken, teamId, ctx).observe(this, teamMembersListMain -> { + teamMembersModel.getMembersByOrgList(instanceToken, teamId, ctx, noDataMembers, progressBar).observe(this, teamMembersListMain -> { adapter = new UserGridAdapter(ctx, teamMembersListMain); @@ -117,9 +118,10 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot @Override public boolean onCreateOptionsMenu(Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.generic_nav_dotted_menu, menu); + if(((OrgPermissions) getIntent().getSerializableExtra("permissions")).isOwner()) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.generic_nav_dotted_menu, menu); + } return true; } diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java index 82581553..d6d86dbc 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java @@ -100,8 +100,16 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter { final Context context = v.getContext(); diff --git a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java index 6c5f4a96..78b01de3 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java @@ -100,6 +100,9 @@ public class MilestonesAdapter extends RecyclerView.Adapter { Context ctx = v.getContext(); diff --git a/app/src/main/java/org/mian/gitnex/adapters/TeamsByOrgAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/TeamsByOrgAdapter.java index 25030a8c..eaba32e4 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/TeamsByOrgAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/TeamsByOrgAdapter.java @@ -10,6 +10,7 @@ import android.widget.Filterable; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; +import org.gitnex.tea4j.models.OrgPermissions; import org.gitnex.tea4j.models.Teams; import org.mian.gitnex.R; import org.mian.gitnex.activities.OrganizationTeamMembersActivity; @@ -25,11 +26,13 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter teamList; private final Context context; private final List teamListFull; + private final OrgPermissions permissions; static class OrgTeamsViewHolder extends RecyclerView.ViewHolder { private Teams teams; + private OrgPermissions permissions; private final TextView teamTitle; private final TextView teamDescription; private final TextView teamPermission; @@ -48,6 +51,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter teamListMain) { + public TeamsByOrgAdapter(Context ctx, List teamListMain, OrgPermissions permissions) { this.context = ctx; this.teamList = teamListMain; + this.permissions = permissions; teamListFull = new ArrayList<>(teamList); } @@ -75,6 +80,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter { bmListener.onButtonClicked("downloadFile"); diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java index 329cd37f..5befcb09 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java @@ -8,8 +8,17 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.gitnex.tea4j.models.OrgPermissions; +import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.BottomSheetOrganizationBinding; import org.mian.gitnex.structs.BottomSheetListener; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Version; +import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -18,6 +27,11 @@ import org.mian.gitnex.structs.BottomSheetListener; public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment { private BottomSheetListener bmListener; + private final OrgPermissions permissions; + + public BottomSheetOrganizationFragment(OrgPermissions org) { + permissions = org; + } @Nullable @Override @@ -25,6 +39,16 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment { BottomSheetOrganizationBinding bottomSheetOrganizationBinding = BottomSheetOrganizationBinding.inflate(inflater, container, false); + if(permissions != null) { + if(!permissions.canCreateRepositories()) { + bottomSheetOrganizationBinding.createRepository.setVisibility(View.GONE); + } + if(!permissions.isOwner()) { + bottomSheetOrganizationBinding.createLabel.setVisibility(View.GONE); + bottomSheetOrganizationBinding.createTeam.setVisibility(View.GONE); + } + } + bottomSheetOrganizationBinding.createTeam.setOnClickListener(v1 -> { bmListener.onButtonClicked("team"); diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java index 6b4bc99a..72f220e6 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java @@ -47,13 +47,32 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment { TextView repoSettings = bottomSheetRepoBinding.repoSettings; TextView createPullRequest = bottomSheetRepoBinding.createPullRequest; + boolean canPush = tinyDb.getBoolean("canPush"); + if(!canPush) { + createMilestone.setVisibility(View.GONE); + createLabel.setVisibility(View.GONE); + createRelease.setVisibility(View.GONE); + newFile.setVisibility(View.GONE); + } + + boolean archived = tinyDb.getBoolean("isArchived"); + if(archived) { + createIssue.setVisibility(View.GONE); + createPullRequest.setVisibility(View.GONE); + createMilestone.setVisibility(View.GONE); + createLabel.setVisibility(View.GONE); + createRelease.setVisibility(View.GONE); + newFile.setVisibility(View.GONE); + bottomSheetRepoBinding.createDivider.setVisibility(View.GONE); + } + createLabel.setOnClickListener(v112 -> { bmListener.onButtonClicked("label"); dismiss(); }); - if(tinyDb.getBoolean("hasIssues")) { + if(tinyDb.getBoolean("hasIssues") && !archived) { createIssue.setVisibility(View.VISIBLE); createIssue.setOnClickListener(v12 -> { @@ -67,7 +86,7 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment { createIssue.setVisibility(View.GONE); } - if(tinyDb.getBoolean("hasPullRequests")) { + if(tinyDb.getBoolean("hasPullRequests") && !archived) { createPullRequest.setVisibility(View.VISIBLE); createPullRequest.setOnClickListener(vPr -> { 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 53bafd72..6bc18676 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java @@ -37,6 +37,11 @@ import java.util.Objects; public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { private BottomSheetListener bmListener; + private final String issueCreator; + + public BottomSheetSingleIssueFragment(String username) { + issueCreator = username; + } @Nullable @Override @@ -47,10 +52,14 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { final Context ctx = getContext(); final TinyDB tinyDB = TinyDB.getInstance(ctx); + boolean userIsCreator = issueCreator.equals(tinyDB.getString("loginUid")); + boolean isRepoAdmin = tinyDB.getBoolean("isRepoAdmin"); + boolean canPush = tinyDB.getBoolean("canPush"); + boolean archived = tinyDB.getBoolean("isArchived"); + TextView editIssue = bottomSheetSingleIssueBinding.editIssue; TextView editLabels = bottomSheetSingleIssueBinding.editLabels; TextView closeIssue = bottomSheetSingleIssueBinding.closeIssue; - TextView reOpenIssue = bottomSheetSingleIssueBinding.reOpenIssue; TextView addRemoveAssignees = bottomSheetSingleIssueBinding.addRemoveAssignees; TextView copyIssueUrl = bottomSheetSingleIssueBinding.copyIssueUrl; TextView openFilesDiff = bottomSheetSingleIssueBinding.openFilesDiff; @@ -60,6 +69,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { TextView shareIssue = bottomSheetSingleIssueBinding.shareIssue; TextView subscribeIssue = bottomSheetSingleIssueBinding.subscribeIssue; TextView unsubscribeIssue = bottomSheetSingleIssueBinding.unsubscribeIssue; + View closeReopenDivider = bottomSheetSingleIssueBinding.dividerCloseReopenIssue; LinearLayout linearLayout = bottomSheetSingleIssueBinding.commentReactionButtons; @@ -100,14 +110,36 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { copyIssueUrl.setText(R.string.copyPrUrlText); shareIssue.setText(R.string.sharePr); + boolean canPushPullSource = tinyDB.getBoolean("canPushPullSource"); if(tinyDB.getBoolean("prMerged") || tinyDB.getString("repoPrState").equals("closed")) { updatePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE); - deletePullRequestBranch.setVisibility(View.VISIBLE); + if(canPushPullSource) { + deletePullRequestBranch.setVisibility(View.VISIBLE); + } + else { + if(!canPush) { + editIssue.setVisibility(View.GONE); + } + deletePullRequestBranch.setVisibility(View.GONE); + } } else { - updatePullRequest.setVisibility(View.VISIBLE); - mergePullRequest.setVisibility(View.VISIBLE); + if(canPushPullSource) { + updatePullRequest.setVisibility(View.VISIBLE); + } + else { + updatePullRequest.setVisibility(View.GONE); + } + if(!userIsCreator && !canPush) { + editIssue.setVisibility(View.GONE); + } + if(canPush && !tinyDB.getString("prMergeable").equals("false")) { + mergePullRequest.setVisibility(View.VISIBLE); + } + else { + mergePullRequest.setVisibility(View.GONE); + } deletePullRequestBranch.setVisibility(View.GONE); } @@ -123,7 +155,9 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { } else { - + if(!userIsCreator && !canPush) { + editIssue.setVisibility(View.GONE); + } updatePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE); deletePullRequestBranch.setVisibility(View.GONE); @@ -199,41 +233,36 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { dismiss(); }); - if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) { - - if(tinyDB.getString("issueState").equals("open")) { // close issue - - reOpenIssue.setVisibility(View.GONE); - closeIssue.setVisibility(View.VISIBLE); - - closeIssue.setOnClickListener(closeSingleIssue -> { - - IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); - dismiss(); - - }); - - } - else if(tinyDB.getString("issueState").equals("closed")) { - + if(tinyDB.getString("issueState").equals("open")) { // close issue + if(!userIsCreator && !canPush) { closeIssue.setVisibility(View.GONE); - reOpenIssue.setVisibility(View.VISIBLE); - - reOpenIssue.setOnClickListener(reOpenSingleIssue -> { - - IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); - dismiss(); - - }); - + closeReopenDivider.setVisibility(View.GONE); } - + else if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { + closeIssue.setText(R.string.closePr); + } + closeIssue.setOnClickListener(closeSingleIssue -> { + IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); + dismiss(); + }); } - else { - - reOpenIssue.setVisibility(View.GONE); - closeIssue.setVisibility(View.GONE); - + else if(tinyDB.getString("issueState").equals("closed")) { + if(userIsCreator || canPush) { + if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { + closeIssue.setText(R.string.reopenPr); + } + else { + closeIssue.setText(R.string.reOpenIssue); + } + } + else { + closeIssue.setVisibility(View.GONE); + closeReopenDivider.setVisibility(View.GONE); + } + closeIssue.setOnClickListener(closeSingleIssue -> { + IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); + dismiss(); + }); } subscribeIssue.setOnClickListener(subscribeToIssue -> { @@ -261,6 +290,18 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { unsubscribeIssue.setVisibility(View.GONE); } + if(archived) { + subscribeIssue.setVisibility(View.GONE); + unsubscribeIssue.setVisibility(View.GONE); + editIssue.setVisibility(View.GONE); + editLabels.setVisibility(View.GONE); + closeIssue.setVisibility(View.GONE); + closeReopenDivider.setVisibility(View.GONE); + addRemoveAssignees.setVisibility(View.GONE); + linearLayout.setVisibility(View.GONE); + bottomSheetSingleIssueBinding.shareDivider.setVisibility(View.GONE); + } + return bottomSheetSingleIssueBinding.getRoot(); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java index 8402642a..601390d5 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java @@ -283,6 +283,7 @@ public class RepoInfoFragment extends Fragment { tinyDb.putBoolean("hasPullRequests", false); } + tinyDb.putBoolean("isArchived", repoInfo.isArchived()); if(repoInfo.isArchived()) { binding.repoIsArchived.setVisibility(View.VISIBLE); } @@ -291,6 +292,7 @@ public class RepoInfoFragment extends Fragment { } tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url()); + tinyDb.putBoolean("canPush", repoInfo.getPermissions().canPush()); binding.progressBar.setVisibility(View.GONE); pageContent.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java b/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java index 4a9f299a..ae9b7c24 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java @@ -22,6 +22,7 @@ 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.OrgPermissions; import org.gitnex.tea4j.models.Teams; import org.mian.gitnex.R; import org.mian.gitnex.adapters.TeamsByOrgAdapter; @@ -44,15 +45,17 @@ public class TeamsByOrgFragment extends Fragment { private TextView noDataTeams; private static String orgNameF = "param2"; private String orgName; + private OrgPermissions permissions; private TeamsByOrgAdapter adapter; public TeamsByOrgFragment() { } - public static TeamsByOrgFragment newInstance(String param1) { + public static TeamsByOrgFragment newInstance(String param1, OrgPermissions permissions) { TeamsByOrgFragment fragment = new TeamsByOrgFragment(); Bundle args = new Bundle(); args.putString(orgNameF, param1); + args.putSerializable("permissions", permissions); fragment.setArguments(args); return fragment; } @@ -62,6 +65,7 @@ public class TeamsByOrgFragment extends Fragment { super.onCreate(savedInstanceState); if (getArguments() != null) { orgName = getArguments().getString(orgNameF); + permissions = (OrgPermissions) getArguments().getSerializable("permissions"); } } @@ -89,7 +93,7 @@ public class TeamsByOrgFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext()); + TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext(), noDataTeams, mProgressBar); }, 200)); @@ -104,7 +108,7 @@ public class TeamsByOrgFragment extends Fragment { TinyDB tinyDb = TinyDB.getInstance(getContext()); if(tinyDb.getBoolean("resumeTeams")) { - TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext()); + TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext(), noDataTeams, mProgressBar); tinyDb.putBoolean("resumeTeams", false); } } @@ -113,10 +117,10 @@ public class TeamsByOrgFragment extends Fragment { TeamsByOrgViewModel teamModel = new ViewModelProvider(this).get(TeamsByOrgViewModel.class); - teamModel.getTeamsByOrg(instanceToken, owner, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + teamModel.getTeamsByOrg(instanceToken, owner, getContext(), noDataTeams, mProgressBar).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List orgTeamsListMain) { - adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain); + adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain, permissions); if(adapter.getItemCount() > 0) { mRecyclerView.setAdapter(adapter); noDataTeams.setVisibility(View.GONE); diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java index e1476c49..c6c9cf1b 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java @@ -2,11 +2,15 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; import androidx.annotation.NonNull; 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.clients.RetrofitClient; import java.util.List; import retrofit2.Call; @@ -21,15 +25,15 @@ public class TeamMembersByOrgViewModel extends ViewModel { private static MutableLiveData> teamMembersList; - public LiveData> getMembersByOrgList(String token, int teamId, Context ctx) { + public LiveData> getMembersByOrgList(String token, int teamId, Context ctx, TextView noDataMembers, ProgressBar progressBar) { teamMembersList = new MutableLiveData<>(); - loadMembersByOrgList(token, teamId, ctx); + loadMembersByOrgList(token, teamId, ctx, noDataMembers, progressBar); return teamMembersList; } - private static void loadMembersByOrgList(String token, int teamId, Context ctx) { + private static void loadMembersByOrgList(String token, int teamId, Context ctx, TextView noDataMembers, ProgressBar progressBar) { Call> call = RetrofitClient .getApiInterface(ctx) @@ -44,13 +48,21 @@ public class TeamMembersByOrgViewModel extends ViewModel { teamMembersList.postValue(response.body()); } else { Log.i("onResponse", String.valueOf(response.code())); + progressBar.setVisibility(View.GONE); + if(response.code() == 403) { + noDataMembers.setText(R.string.authorizeError); + } else { + noDataMembers.setText(R.string.genericError); + } } } @Override - public void onFailure(@NonNull Call> call, Throwable t) { + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { Log.i("onFailure", t.toString()); + progressBar.setVisibility(View.GONE); + noDataMembers.setText(R.string.genericError); } }); diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java index 1d2a9fc5..b9ea6c81 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java @@ -2,12 +2,17 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import org.gitnex.tea4j.models.Teams; +import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.helpers.Toasty; import java.util.List; import retrofit2.Call; import retrofit2.Callback; @@ -21,15 +26,15 @@ public class TeamsByOrgViewModel extends ViewModel { private static MutableLiveData> teamsList; - public LiveData> getTeamsByOrg(String token, String orgName, Context ctx) { + public LiveData> getTeamsByOrg(String token, String orgName, Context ctx, TextView noDataTeams, ProgressBar mProgressBar) { teamsList = new MutableLiveData<>(); - loadTeamsByOrgList(token, orgName, ctx); + loadTeamsByOrgList(token, orgName, ctx, noDataTeams, mProgressBar); return teamsList; } - public static void loadTeamsByOrgList(String token, String orgName, Context ctx) { + public static void loadTeamsByOrgList(String token, String orgName, Context ctx, TextView noDataTeams, ProgressBar mProgressBar) { Call> call = RetrofitClient .getApiInterface(ctx) @@ -46,12 +51,23 @@ public class TeamsByOrgViewModel extends ViewModel { } } + else if(response.code() == 403) { + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + mProgressBar.setVisibility(View.GONE); + noDataTeams.setText(R.string.authorizeError); + } + else { + mProgressBar.setVisibility(View.GONE); + noDataTeams.setText(R.string.genericError); + } } @Override - public void onFailure(@NonNull Call> call, Throwable t) { + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { Log.i("onFailure", t.toString()); + mProgressBar.setVisibility(View.GONE); + noDataTeams.setText(R.string.genericError); } }); diff --git a/app/src/main/res/layout/activity_edit_issue.xml b/app/src/main/res/layout/activity_edit_issue.xml index d4dfb485..ee12a25a 100644 --- a/app/src/main/res/layout/activity_edit_issue.xml +++ b/app/src/main/res/layout/activity_edit_issue.xml @@ -149,7 +149,6 @@ android:layout_marginBottom="8dp" app:endIconMode="clear_text" app:endIconTint="?attr/iconsColor" - android:visibility="gone" android:hint="@string/newIssueDueDateTitle"> - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9048124e..3292b270 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -749,6 +749,9 @@ Merge Rebase Select Update Strategy + + Close Pull Request + Reopen Pull Request Avatar Use Custom Tabs No application found to open this link. SSH URLs and URLs with another prefix the http:// or https:// are not supported by most browser