Transfer repository ownership (#696)

simplify comments

Transfer repository ownership

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/696
This commit is contained in:
M M Arif 2020-09-16 08:53:13 +02:00
parent c4279dcd77
commit a75ffe0381
7 changed files with 322 additions and 2 deletions

View File

@ -94,8 +94,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
// if gitea is 1.12 or higher use the new limit
// require gitea 1.12 or higher
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}

View File

@ -17,8 +17,11 @@ import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.databinding.ActivityRepositorySettingsBinding;
import org.mian.gitnex.databinding.CustomRepositoryDeleteDialogBinding;
import org.mian.gitnex.databinding.CustomRepositoryEditPropertiesDialogBinding;
import org.mian.gitnex.databinding.CustomRepositoryTransferDialogBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.RepositoryTransfer;
import org.mian.gitnex.models.UserRepositories;
import retrofit2.Call;
import retrofit2.Callback;
@ -32,8 +35,10 @@ public class RepositorySettingsActivity extends BaseActivity {
private ActivityRepositorySettingsBinding viewBinding;
private CustomRepositoryEditPropertiesDialogBinding propBinding;
private CustomRepositoryDeleteDialogBinding deleteRepoBinding;
private CustomRepositoryTransferDialogBinding transferRepoBinding;
private Dialog dialogProp;
private Dialog dialogDeleteRepository;
private Dialog dialogTransferRepository;
private View.OnClickListener onClickListener;
private Context ctx = this;
private Context appCtx;
@ -75,14 +80,116 @@ public class RepositorySettingsActivity extends BaseActivity {
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
// require gitea 1.12 or higher
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
viewBinding.transferOwnerFrame.setVisibility(View.VISIBLE);
}
viewBinding.editProperties.setOnClickListener(editProperties -> {
showRepositoryProperties();
});
viewBinding.deleteRepository.setOnClickListener(editProperties -> {
viewBinding.deleteRepository.setOnClickListener(deleteRepository -> {
showDeleteRepository();
});
viewBinding.transferOwnerFrame.setOnClickListener(transferRepositoryOwnership -> {
showTransferRepository();
});
}
private void showTransferRepository() {
dialogTransferRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogTransferRepository.getWindow() != null) {
dialogTransferRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
transferRepoBinding = CustomRepositoryTransferDialogBinding.inflate(LayoutInflater.from(ctx));
View view = transferRepoBinding.getRoot();
dialogTransferRepository.setContentView(view);
transferRepoBinding.cancel.setOnClickListener(editProperties -> {
dialogTransferRepository.dismiss();
});
transferRepoBinding.transfer.setOnClickListener(deleteRepo -> {
String newOwner = String.valueOf(transferRepoBinding.ownerNameForTransfer.getText());
String repoName = String.valueOf(transferRepoBinding.repoNameForTransfer.getText());
if(!repositoryName.equals(repoName)) {
Toasty.error(ctx, getString(R.string.repoSettingsDeleteError));
}
else if(newOwner.matches("")) {
Toasty.error(ctx, getString(R.string.repoTransferOwnerError));
}
else {
transferRepository(newOwner);
}
});
dialogTransferRepository.show();
}
private void transferRepository(String newOwner) {
RepositoryTransfer repositoryTransfer = new RepositoryTransfer(newOwner);
Call<JsonElement> transferCall = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.transferRepository(instanceToken, repositoryOwner, repositoryName, repositoryTransfer);
transferCall.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
transferRepoBinding.transfer.setVisibility(View.GONE);
transferRepoBinding.processingRequest.setVisibility(View.VISIBLE);
if (response.code() == 202) {
dialogTransferRepository.dismiss();
Toasty.success(ctx, getString(R.string.repoTransferSuccess));
finish();
RepositoriesApi.deleteRepository((int) tinyDb.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
else if (response.code() == 404) {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.repoTransferError));
}
else {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void showDeleteRepository() {
@ -144,6 +251,8 @@ public class RepositorySettingsActivity extends BaseActivity {
}
else {
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
@ -152,6 +261,8 @@ public class RepositorySettingsActivity extends BaseActivity {
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
@ -297,6 +408,8 @@ public class RepositorySettingsActivity extends BaseActivity {
}
else {
propBinding.save.setVisibility(View.VISIBLE);
propBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
@ -305,6 +418,8 @@ public class RepositorySettingsActivity extends BaseActivity {
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
propBinding.save.setVisibility(View.VISIBLE);
propBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});

View File

@ -26,6 +26,7 @@ import org.mian.gitnex.models.OrganizationRepository;
import org.mian.gitnex.models.Permission;
import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.models.Releases;
import org.mian.gitnex.models.RepositoryTransfer;
import org.mian.gitnex.models.Teams;
import org.mian.gitnex.models.UpdateIssueAssignees;
import org.mian.gitnex.models.UpdateIssueState;
@ -133,6 +134,9 @@ public interface ApiInterface {
@DELETE("repos/{owner}/{repo}") // delete repository
Call<JsonElement> deleteRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@POST("repos/{owner}/{repo}/transfer") // transfer repository
Call<JsonElement> transferRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body RepositoryTransfer jsonStr);
@GET("repos/{owner}/{repo}/issues") // get issues by repo
Call<List<Issues>> getIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("limit") int limit, @Query("type") String requestType, @Query("state") String issueState);

View File

@ -0,0 +1,20 @@
package org.mian.gitnex.models;
/**
* Author M M Arif
*/
public class RepositoryTransfer {
private String new_owner;
public RepositoryTransfer(String new_owner) {
this.new_owner = new_owner;
}
public String getNew_owner() {
return new_owner;
}
}

View File

@ -68,6 +68,46 @@
android:layout_height="1dp"
android:background="?attr/dividerColor" />
<LinearLayout
android:id="@+id/transferOwnerFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/transferRepositoryOwnership"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/repoSettingsTransferOwnership"
android:drawableStart="@drawable/ic_arrow_up"
android:drawablePadding="32dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:paddingTop="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
<TextView
android:id="@+id/transferRepositoryOwnershipHint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/repoSettingsTransferOwnershipHint"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:paddingBottom="16dp"
android:paddingStart="72dp"
android:paddingEnd="16dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/shape_custom_dialog"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:textSize="20sp"
android:textStyle="bold"
android:drawableStart="@drawable/ic_arrow_up"
android:drawablePadding="16dp"
android:text="@string/repoSettingsTransferOwnership"
android:layout_marginBottom="16dp" />
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:text="@string/repoSettingsTransferOwnershipDescription"
android:layout_marginBottom="16dp" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/repoNameForTransferLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxBackgroundColor="?attr/inputBackgroundColor"
android:textColorHint="?attr/hintColor"
app:hintTextColor="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
android:layout_marginBottom="8dp"
android:hint="@string/newRepoTintCopy">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/repoNameForTransfer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/ownerNameForTransferLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxBackgroundColor="?attr/inputBackgroundColor"
android:textColorHint="?attr/hintColor"
app:hintTextColor="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
android:layout_marginBottom="8dp"
android:hint="@string/repoTransferOwnerText">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ownerNameForTransfer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:id="@+id/divider"
android:background="?attr/dividerColor" />
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/processingRequest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
app:indicatorColor="?attr/progressIndicatorColor" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:orientation="horizontal" >
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/button"
android:layout_alignParentStart="true"
android:text="@string/cancelButton"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
<Button
android:id="@+id/transfer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/button"
android:layout_alignParentEnd="true"
android:text="@string/repoTransferText"
android:backgroundTint="@color/darkRed"
android:textColor="@color/colorWhite"
android:textSize="16sp"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
</LinearLayout>

View File

@ -682,5 +682,13 @@
<string name="repoSettingsDeleteDescription">Things to know before deletion:\n\n- This operation CANNOT be undone.\n- This operation will permanently delete the repository including code, issues, comments, wiki data and collaborator settings.\n\nEnter the repository name as confirmation</string>
<string name="repoSettingsDeleteError">Repository name does not match</string>
<string name="repoDeletionSuccess">Repository deleted successfully</string>
<string name="repoSettingsTransferOwnership">Transfer Ownership</string>
<string name="repoSettingsTransferOwnershipHint">Transfer this repository to a user or to an organization for which you have administrator rights</string>
<string name="repoSettingsTransferOwnershipDescription">Things to know before transfer:\n\n- You will lose access to the repository if you transfer it to an individual user.\n- You will keep access to the repository if you transfer it to an organization that you (co-)own.\n\nEnter the repository name as confirmation</string>
<string name="repoTransferText">Perform Transfer</string>
<string name="repoTransferOwnerText">New Owner</string>
<string name="repoTransferSuccess">Repository transferred successfully</string>
<string name="repoTransferOwnerError">New owner is required</string>
<string name="repoTransferError">There is a problem with the owner name. Make sure that the new owner exists</string>
</resources>