mirror of
https://codeberg.org/gitnex/GitNex.git
synced 2023-12-13 20:50:18 +01:00
d3cc481a4d
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>
252 lines
9.5 KiB
Java
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);
|
|
}
|
|
}
|
|
|
|
}
|