GitNex/app/src/main/java/org/mian/gitnex/fragments/CommitDetailFragment.java
qwerty287 d3cc481a4d Add support for PR commits (#1152)
Can be found under the changes option of PRs.

Closes https://codeberg.org/gitnex/GitNex/issues/332

Co-authored-by: qwerty287 <ndev@web.de>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1152
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2022-06-30 12:36:13 +02:00

252 lines
9.5 KiB
Java

package org.mian.gitnex.fragments;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.text.HtmlCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.v2.models.Commit;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.BaseActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.adapters.DiffFilesAdapter;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentCommitDetailsBinding;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FileDiffView;
import org.mian.gitnex.helpers.ParseDiff;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* @author qwerty287
*/
public class CommitDetailFragment extends Fragment {
private FragmentCommitDetailsBinding binding;
private String repoOwner;
private String repoName;
private String sha;
private List<FileDiffView> fileDiffViews = new ArrayList<>();
private DiffFilesAdapter adapter;
private int loadingFinished = 0;
public static CommitDetailFragment newInstance() {
return new CommitDetailFragment();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
if(binding != null) return binding.getRoot();
binding = FragmentCommitDetailsBinding.inflate(getLayoutInflater(), container, false);
IssueContext issue = IssueContext.fromIntent(requireActivity().getIntent());
RepositoryContext repository = RepositoryContext.fromIntent(requireActivity().getIntent());
repoOwner = repository.getOwner();
repoName = repository.getName();
sha = requireActivity().getIntent().getStringExtra("sha");
binding.toolbarTitle.setText(sha.substring(0, Math.min(sha.length(), 10)));
adapter = new DiffFilesAdapter(requireContext(), fileDiffViews, issue, "commit");
binding.diffFiles.setHasFixedSize(true);
binding.diffFiles.setLayoutManager(new LinearLayoutManager(requireContext()));
binding.diffFiles.setAdapter(adapter);
getCommit();
getDiff();
binding.close.setOnClickListener((v) -> requireActivity().finish());
return binding.getRoot();
}
private void getDiff() {
Call<String> call = ((BaseActivity) requireActivity()).getAccount().requiresVersion("1.16.0") ?
RetrofitClient.getApiInterface(requireContext()).repoDownloadCommitDiffOrPatch(repoOwner, repoName, sha, "diff") :
RetrofitClient.getWebInterface(requireContext()).repoDownloadCommitDiffOrPatch(repoOwner, repoName, sha, "diff");
call.enqueue(new Callback<>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
checkLoading();
switch(response.code()) {
case 200:
assert response.body() != null;
fileDiffViews = ParseDiff.getFileDiffViewArray(response.body());
requireActivity().runOnUiThread(() -> {
adapter.updateList(fileDiffViews);
adapter.notifyDataChanged();
});
break;
case 401:
requireActivity().runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(requireContext()));
break;
case 403:
requireActivity().runOnUiThread(() -> Toasty.error(requireContext(), getString(R.string.authorizeError)));
break;
case 404:
requireActivity().runOnUiThread(() -> Toasty.warning(requireContext(), getString(R.string.apiNotFound)));
break;
default:
requireActivity().runOnUiThread(() -> Toasty.error(requireContext(), getString(R.string.genericError)));
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
checkLoading();
if(getContext() != null) Toasty.error(requireContext(), getString(R.string.genericError));
}
});
}
private void getCommit() {
RetrofitClient.getApiInterface(requireContext()).repoGetSingleCommit(repoOwner, repoName, sha)
.enqueue(new Callback<>() {
@Override
public void onResponse(@NonNull Call<Commit> call, @NonNull Response<Commit> response) {
checkLoading();
Commit commitsModel = response.body();
if(commitsModel == null) {
onFailure(call, new Throwable());
return;
}
String[] commitMessageParts = commitsModel.getCommit().getMessage().split("(\r\n|\n)", 2);
if(commitMessageParts.length > 1 && !commitMessageParts[1].trim().isEmpty()) {
binding.commitBody.setVisibility(View.VISIBLE);
binding.commitSubject.setText(EmojiParser.parseToUnicode(commitMessageParts[0].trim()));
binding.commitBody.setText(EmojiParser.parseToUnicode(commitMessageParts[1].trim()));
}
else {
binding.commitSubject.setText(EmojiParser.parseToUnicode(commitMessageParts[0].trim()));
binding.commitBody.setVisibility(View.GONE);
}
if(!Objects.equals(commitsModel.getCommit().getCommitter().getEmail(), commitsModel.getCommit().getCommitter().getEmail())) {
binding.commitAuthorAndCommitter.setText(HtmlCompat.fromHtml(
CommitDetailFragment.this.getString(R.string.commitAuthoredByAndCommittedByWhen, commitsModel.getCommit().getAuthor().getName(), commitsModel.getCommit().getCommitter().getName(),
TimeHelper.formatTime(TimeHelper.parseIso8601(commitsModel.getCommit().getCommitter().getDate()), getResources().getConfiguration().locale, "pretty",
requireContext())), HtmlCompat.FROM_HTML_MODE_COMPACT));
}
else {
binding.commitAuthorAndCommitter.setText(HtmlCompat.fromHtml(
CommitDetailFragment.this.getString(R.string.commitCommittedByWhen, commitsModel.getCommit().getCommitter().getName(),
TimeHelper.formatTime(TimeHelper.parseIso8601(commitsModel.getCommit().getCommitter().getDate()), getResources().getConfiguration().locale, "pretty",
requireContext())), HtmlCompat.FROM_HTML_MODE_COMPACT));
}
if(commitsModel.getAuthor() != null && commitsModel.getAuthor().getAvatarUrl() != null && !commitsModel.getAuthor().getAvatarUrl()
.isEmpty()) {
binding.commitAuthorAvatar.setVisibility(View.VISIBLE);
int imgRadius = AppUtil.getPixelsFromDensity(requireContext(), 3);
PicassoService.getInstance(requireContext()).get().load(commitsModel.getAuthor().getAvatarUrl())
.placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(binding.commitAuthorAvatar);
binding.commitAuthorAvatar.setOnClickListener((v) -> {
Intent intent = new Intent(requireContext(), ProfileActivity.class);
intent.putExtra("username", commitsModel.getAuthor().getLogin());
startActivity(intent);
});
}
else {
binding.commitAuthorAvatar.setImageDrawable(null);
binding.commitAuthorAvatar.setVisibility(View.GONE);
}
if(commitsModel.getCommitter() != null && (commitsModel.getAuthor() == null || !commitsModel.getAuthor().getLogin()
.equals(commitsModel.getCommitter().getLogin())) && commitsModel.getCommitter().getAvatarUrl() != null && !commitsModel.getCommitter().getAvatarUrl().isEmpty()) {
binding.commitCommitterAvatar.setVisibility(View.VISIBLE);
int imgRadius = AppUtil.getPixelsFromDensity(requireContext(), 3);
PicassoService.getInstance(requireContext()).get().load(commitsModel.getCommitter().getAvatarUrl())
.placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(binding.commitCommitterAvatar);
binding.commitCommitterAvatar.setOnClickListener((v) -> {
Intent intent = new Intent(requireContext(), ProfileActivity.class);
intent.putExtra("username", commitsModel.getCommitter().getLogin());
startActivity(intent);
});
}
else {
binding.commitCommitterAvatar.setImageDrawable(null);
binding.commitCommitterAvatar.setVisibility(View.GONE);
}
binding.commitSha.setText(commitsModel.getSha().substring(0, Math.min(commitsModel.getSha().length(), 10)));
binding.commitSha.setOnClickListener((v) -> {
ClipboardManager clipboard = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("commitSha", commitsModel.getSha());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.success(requireContext(), getString(R.string.copyShaToastMsg));
});
}
@Override
public void onFailure(@NonNull Call<Commit> call, @NonNull Throwable t) {
checkLoading();
if(getContext() != null) {
Toasty.error(requireContext(), getString(R.string.genericError));
requireActivity().finish();
}
}
});
}
private void checkLoading() {
loadingFinished += 1;
if(loadingFinished >= 2) {
binding.progressBar.setVisibility(View.GONE);
}
}
}