Browse Source

Share comment of an issue (#348)

cleanup

Use html_url to fix issue/pr separation

Share comment of an issue

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: #348
Reviewed-by: 6543 <6543@noreply.gitea.io>
tags/2.5.0-rc4
M M Arif 1 month ago
parent
commit
9e77e27177
5 changed files with 245 additions and 184 deletions
  1. +2
    -2
      .idea/codeStyles/Project.xml
  2. +218
    -182
      app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
  3. +12
    -0
      app/src/main/res/layout/bottom_sheet_issue_comments.xml
  4. +12
    -0
      app/src/main/res/layout/list_issue_comments.xml
  5. +1
    -0
      app/src/main/res/values/strings.xml

+ 2
- 2
.idea/codeStyles/Project.xml View File

@@ -17,7 +17,7 @@
</option>
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="120" />
<option name="RIGHT_MARGIN" value="220" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
@@ -156,4 +156,4 @@
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
</component>

+ 218
- 182
app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java View File

@@ -56,56 +56,85 @@ import io.noties.markwon.linkify.LinkifyPlugin;

public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {

private List<IssueComments> issuesComments;
private Context mCtx;
private List<IssueComments> issuesComments;
private Context mCtx;

static class IssueCommentViewHolder extends RecyclerView.ViewHolder {
static class IssueCommentViewHolder extends RecyclerView.ViewHolder {

private TextView issueNumber;
private TextView commendId;
private ImageView issueCommenterAvatar;
private TextView issueComment;
private TextView issueCommentDate;
private ImageView commentsOptionsMenu;
private TextView commendBodyRaw;
private TextView commentModified;
private TextView issueNumber;
private TextView commendId;
private ImageView issueCommenterAvatar;
private TextView issueComment;
private TextView issueCommentDate;
private ImageView commentsOptionsMenu;
private TextView commendBodyRaw;
private TextView commentModified;
private TextView commenterUsername;
private TextView htmlUrl;

private IssueCommentViewHolder(View itemView) {
super(itemView);
private IssueCommentViewHolder(View itemView) {

issueNumber = itemView.findViewById(R.id.issueNumber);
commendId = itemView.findViewById(R.id.commendId);
issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
issueComment = itemView.findViewById(R.id.issueComment);
issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
commentModified = itemView.findViewById(R.id.commentModified);
super(itemView);

commentsOptionsMenu.setOnClickListener(v -> {
issueNumber = itemView.findViewById(R.id.issueNumber);
commendId = itemView.findViewById(R.id.commendId);
issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
issueComment = itemView.findViewById(R.id.issueComment);
issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
commentModified = itemView.findViewById(R.id.commentModified);
commenterUsername = itemView.findViewById(R.id.commenterUsername);
htmlUrl = itemView.findViewById(R.id.htmlUrl);

final Context context = v.getContext();
commentsOptionsMenu.setOnClickListener(v -> {

@SuppressLint("InflateParams")
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);
final Context context = v.getContext();
final TinyDB tinyDb = new TinyDB(context);
final String loginUid = tinyDb.getString("loginUid");

TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit);
//TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);

BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit);
TextView commentShare = view.findViewById(R.id.issueCommentShare);
//TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);

commentMenuEdit.setOnClickListener(ediComment -> {
if(!loginUid.contentEquals(commenterUsername.getText())) {
commentMenuEdit.setVisibility(View.GONE);
//commentMenuDelete.setVisibility(View.GONE);
}

Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText());
intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText());
context.startActivity(intent);
dialog.dismiss();
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();

commentMenuEdit.setOnClickListener(ediComment -> {

Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText());
intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText());
context.startActivity(intent);
dialog.dismiss();

});

commentShare.setOnClickListener(ediComment -> {

// get comment Url
CharSequence commentUrl = htmlUrl.getText();

// share issue comment
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
String intentHeader = tinyDb.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl);
context.startActivity(Intent.createChooser(sharingIntent, intentHeader));

});
dialog.dismiss();

});

/*commentMenuDelete.setOnClickListener(deleteComment -> {

@@ -113,149 +142,156 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap

});*/

});

}
}

public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
this.mCtx = mCtx;
this.issuesComments = issuesCommentsMain;
}

@NonNull
@Override
public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.issue_comments, parent, false);
return new IssueCommentsAdapter.IssueCommentViewHolder(v);
}

@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {

final TinyDB tinyDb = new TinyDB(mCtx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
final String loginUid = tinyDb.getString("loginUid");

IssueComments currentItem = issuesComments.get(position);

if(!loginUid.equals(currentItem.getUser().getUsername())) {
holder.commentsOptionsMenu.setVisibility(View.INVISIBLE);
}
holder.commendId.setText(String.valueOf(currentItem.getId()));
holder.commendBodyRaw.setText(currentItem.getBody());

if (!currentItem.getUser().getFull_name().equals("")) {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
} else {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
}

PicassoService.getInstance(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);

String cleanIssueComments = currentItem.getBody().trim();

final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {

final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
mCtx.getPackageName());

final Drawable drawable = mCtx.getDrawable(resourceId);

assert drawable != null;
return ImageItem.withResult(drawable);
}

@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();

Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));

String edited;

if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {
edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
holder.commentModified.setVisibility(View.VISIBLE);
holder.commentModified.setText(edited);
holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));
}
else {
holder.commentModified.setVisibility(View.INVISIBLE);
}

switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}
}

}

@Override
public int getItemCount() {
return issuesComments.size();
}
});

}

}

public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {

this.mCtx = mCtx;
this.issuesComments = issuesCommentsMain;

}

@NonNull
@Override
public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issue_comments, parent, false);
return new IssueCommentsAdapter.IssueCommentViewHolder(v);

}

@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {

final TinyDB tinyDb = new TinyDB(mCtx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");

IssueComments currentItem = issuesComments.get(position);

holder.htmlUrl.setText(currentItem.getHtml_url());
holder.commenterUsername.setText(currentItem.getUser().getUsername());
holder.commendId.setText(String.valueOf(currentItem.getId()));
holder.commendBodyRaw.setText(currentItem.getBody());

if(!currentItem.getUser().getFull_name().equals("")) {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
}
else {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
}

PicassoService.getInstance(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);

String cleanIssueComments = currentItem.getBody().trim();

final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)).usePlugin(CorePlugin.create()).usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {

@Override
public void configureImages(@NonNull ImagesPlugin plugin) {

plugin.addSchemeHandler(new SchemeHandler() {

@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {

final int resourceId = mCtx.getResources().getIdentifier(raw.substring("drawable://".length()), "drawable", mCtx.getPackageName());

final Drawable drawable = mCtx.getDrawable(resourceId);

assert drawable != null;
return ImageItem.withResult(drawable);

}

@NonNull
@Override
public Collection<String> supportedSchemes() {

return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {

@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {

return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
})).usePlugin(new AbstractMarkwonPlugin() {

@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {

builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")).linkColor(mCtx.getResources().getColor(R.color.lightBlue));
}

}).usePlugin(TablePlugin.create(mCtx)).usePlugin(TaskListPlugin.create(mCtx)).usePlugin(HtmlPlugin.create()).usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build();

Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));

String edited;

if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {

edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
holder.commentModified.setVisibility(View.VISIBLE);
holder.commentModified.setText(edited);
holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));

}
else {

holder.commentModified.setVisibility(View.INVISIBLE);

}

switch(timeFormat) {

case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}

}

}

@Override
public int getItemCount() {

return issuesComments.size();

}

}

+ 12
- 0
app/src/main/res/layout/bottom_sheet_issue_comments.xml View File

@@ -29,6 +29,18 @@
android:textSize="16sp"
android:padding="16dp" />

<TextView
android:id="@+id/issueCommentShare"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/issueCommentShare"
android:drawableStart="@drawable/ic_share_24dp"
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />

<TextView
android:id="@+id/commentMenuDelete"
android:layout_width="match_parent"


app/src/main/res/layout/issue_comments.xml → app/src/main/res/layout/list_issue_comments.xml View File

@@ -28,6 +28,18 @@
android:layout_height="wrap_content"
android:visibility="gone"/>

<TextView
android:id="@+id/commenterUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>

<TextView
android:id="@+id/htmlUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>

<ImageView
android:id="@+id/issueCommenterAvatar"
android:layout_width="48dp"

+ 1
- 0
app/src/main/res/values/strings.xml View File

@@ -588,4 +588,5 @@
<string name="mtm_decision_once">Once</string>
<string name="mtm_decision_abort">Abort</string>

<string name="issueCommentShare">Share Comment</string>
</resources>

Loading…
Cancel
Save