Merge branch '62-improve-issues-ui' of mmarif/GitNex into master

This commit is contained in:
M M Arif 2019-09-30 18:09:47 +00:00 committed by Gitea
commit 61a1a4446f
18 changed files with 472 additions and 343 deletions

View File

@ -23,8 +23,8 @@ android {
} }
dependencies { dependencies {
def lifecycle_version = "2.2.0-alpha04" def lifecycle_version = "2.2.0-alpha05"
final def markwon_version = "3.0.0" final def markwon_version = "4.1.1"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
@ -47,17 +47,21 @@ dependencies {
implementation "com.vdurmont:emoji-java:4.0.0" implementation "com.vdurmont:emoji-java:4.0.0"
implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "com.pes.materialcolorpicker:library:1.2.5"
implementation "ru.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:core:$markwon_version"
implementation "ru.noties.markwon:ext-strikethrough:$markwon_version" implementation "io.noties.markwon:ext-latex:$markwon_version"
implementation "ru.noties.markwon:ext-tables:$markwon_version" implementation "io.noties.markwon:ext-strikethrough:$markwon_version"
implementation "ru.noties.markwon:ext-tasklist:$markwon_version" implementation "io.noties.markwon:ext-tables:$markwon_version"
implementation "ru.noties.markwon:syntax-highlight:$markwon_version" implementation "io.noties.markwon:ext-tasklist:$markwon_version"
implementation "ru.noties.markwon:image-okhttp:$markwon_version" implementation "io.noties.markwon:html:$markwon_version"
implementation "ru.noties.markwon:html:$markwon_version" implementation "io.noties.markwon:image:$markwon_version"
implementation "ru.noties.markwon:recycler:$markwon_version" implementation "io.noties.markwon:image-picasso:$markwon_version"
implementation "ru.noties.markwon:recycler-table:$markwon_version" implementation "io.noties.markwon:linkify:$markwon_version"
implementation "ru.noties.markwon:image-gif:$markwon_version" implementation "io.noties.markwon:recycler:$markwon_version"
implementation "ru.noties.markwon:image-svg:$markwon_version" implementation "io.noties.markwon:recycler-table:$markwon_version"
implementation "io.noties.markwon:simple-ext:$markwon_version"
implementation "io.noties.markwon:syntax-highlight:$markwon_version"
implementation "com.caverock:androidsvg:1.4"
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.14"
implementation "com.hendraanggrian.appcompat:socialview:0.2" implementation "com.hendraanggrian.appcompat:socialview:0.2"
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2" implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"

View File

@ -10,26 +10,33 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.Spanned;
import android.util.Log; import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.Menu; import android.view.Menu;
@ -63,6 +70,8 @@ import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@ -286,22 +295,60 @@ public class IssueDetailActivity extends AppCompatActivity {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext())) final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext()))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.createWithAssets(getApplicationContext())) @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 = getApplicationContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getApplicationContext().getPackageName());
final Drawable drawable = getApplicationContext().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(getApplicationContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getApplicationContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder builder
.codeTextColor(tinyDb.getInt("codeBlockColor")) .codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getApplicationContext().getResources().getColor(R.color.lightBlue)); .linkColor(getResources().getColor(R.color.lightBlue));
} }
}) })
.usePlugin(TablePlugin.create(getApplicationContext())) .usePlugin(TablePlugin.create(getApplicationContext()))
.usePlugin(TaskListPlugin.create(getApplicationContext())) .usePlugin(TaskListPlugin.create(getApplicationContext()))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build(); .build();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -313,8 +360,8 @@ public class IssueDetailActivity extends AppCompatActivity {
Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(assigneeAvatar); Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(assigneeAvatar);
issueTitle.setText(getString(R.string.issueTitleWithId, singleIssue.getNumber(), singleIssue.getTitle())); issueTitle.setText(getString(R.string.issueTitleWithId, singleIssue.getNumber(), singleIssue.getTitle()));
String cleanIssueDescription = singleIssue.getBody().trim(); String cleanIssueDescription = singleIssue.getBody().trim();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription)); markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription));
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams(); RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams();

View File

@ -3,22 +3,21 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
@ -27,22 +26,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
/** /**
* Author M M Arif * Author M M Arif
@ -122,8 +107,6 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private TextView issueNumber; private TextView issueNumber;
private ImageView issueAssigneeAvatar; private ImageView issueAssigneeAvatar;
private TextView issueTitle; private TextView issueTitle;
private TextView issueDescription;
//private ImageView issueState;
private TextView issueCreatedTime; private TextView issueCreatedTime;
private TextView issueCommentsCount; private TextView issueCommentsCount;
private ImageView issueType; private ImageView issueType;
@ -135,9 +118,8 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
issueNumber = itemView.findViewById(R.id.issueNumber); issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle); issueTitle = itemView.findViewById(R.id.issueTitle);
issueDescription = itemView.findViewById(R.id.issueDescription);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
//issueState = itemView.findViewById(R.id.issueStatus); LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime); issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueType = itemView.findViewById(R.id.issueType); issueType = itemView.findViewById(R.id.issueType);
@ -157,7 +139,7 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} }
}); });
issueDescription.setOnClickListener(new View.OnClickListener() { frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -183,26 +165,6 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
if (!issuesModel.getUser().getFull_name().equals("")) { if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context)); issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else { } else {
@ -210,9 +172,9 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} }
if (issuesModel.getUser().getAvatar_url() != null) { if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar); Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else { } else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar); Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} }
if (issuesModel.getPull_request() == null) { if (issuesModel.getPull_request() == null) {
@ -223,28 +185,12 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context)); issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
} }
issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle()); String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber())); issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments())); issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
if (!issuesModel.getBody().equals("")) {
String cleanIssueDescription = issuesModel.getBody().trim();
issueDescription.setVisibility(View.VISIBLE);
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
}
else {
issueDescription.setText("");
issueDescription.setVisibility(View.GONE);
}
/*if (issuesModel.getState().equals("open")) {
issueState.setImageResource(R.drawable.ic_issue_open);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
} else {
issueState.setImageResource(R.drawable.ic_issue_closed);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
}*/
switch (timeFormat) { switch (timeFormat) {
case "pretty": { case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale)); PrettyTime prettyTime = new PrettyTime(new Locale(locale));

View File

@ -3,7 +3,9 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -14,7 +16,6 @@ import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity; import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
@ -24,26 +25,32 @@ import org.ocpsoft.prettytime.PrettyTime;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon;
import ru.noties.markwon.Markwon; import io.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.CorePlugin; import io.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.ext.tables.TableTheme; import io.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.image.AsyncDrawable;
import ru.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.DefaultMediaDecoder;
import ru.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImageItem;
import ru.noties.markwon.image.gif.GifPlugin; import io.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin; import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
/** /**
* Author M M Arif * Author M M Arif
@ -180,25 +187,63 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.create(mCtx)) @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() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder builder
.codeTextColor(tinyDb.getInt("codeBlockColor")) .codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground")); .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
} }
}) })
.usePlugin(TablePlugin.create(mCtx)) .usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx)) .usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build(); .build();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments)); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
holder.issueComment.setText(UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments)); markwon.setParsedMarkdown(holder.issueComment, bodyWithMD);
String edited; String edited;

View File

@ -3,22 +3,21 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
@ -27,22 +26,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
/** /**
* Author M M Arif * Author M M Arif
@ -122,8 +107,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private TextView issueNumber; private TextView issueNumber;
private ImageView issueAssigneeAvatar; private ImageView issueAssigneeAvatar;
private TextView issueTitle; private TextView issueTitle;
private TextView issueDescription;
//private ImageView issueState;
private TextView issueCreatedTime; private TextView issueCreatedTime;
private TextView issueCommentsCount; private TextView issueCommentsCount;
private ImageView issueType; private ImageView issueType;
@ -135,9 +118,8 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
issueNumber = itemView.findViewById(R.id.issueNumber); issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle); issueTitle = itemView.findViewById(R.id.issueTitle);
issueDescription = itemView.findViewById(R.id.issueDescription);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
//issueState = itemView.findViewById(R.id.issueStatus); LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime); issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueType = itemView.findViewById(R.id.issueType); issueType = itemView.findViewById(R.id.issueType);
@ -157,7 +139,7 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} }
}); });
issueDescription.setOnClickListener(new View.OnClickListener() { frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -183,26 +165,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
if (!issuesModel.getUser().getFull_name().equals("")) { if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context)); issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else { } else {
@ -210,9 +172,9 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} }
if (issuesModel.getUser().getAvatar_url() != null) { if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar); Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else { } else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar); Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} }
if (issuesModel.getPull_request() == null) { if (issuesModel.getPull_request() == null) {
@ -223,28 +185,12 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context)); issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
} }
issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle()); String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber())); issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments())); issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
if (!issuesModel.getBody().equals("")) {
String cleanIssueDescription = issuesModel.getBody().trim();
issueDescription.setVisibility(View.VISIBLE);
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
}
else {
issueDescription.setText("");
issueDescription.setVisibility(View.GONE);
}
/*if (issuesModel.getState().equals("open")) {
issueState.setImageResource(R.drawable.ic_issue_open);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
} else {
issueState.setImageResource(R.drawable.ic_issue_closed);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
}*/
switch (timeFormat) { switch (timeFormat) {
case "pretty": { case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale)); PrettyTime prettyTime = new PrettyTime(new Locale(locale));

View File

@ -3,6 +3,9 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -22,25 +25,31 @@ import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon;
import ru.noties.markwon.Markwon; import io.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.CorePlugin; import io.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.ext.tables.TableTheme; import io.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.image.AsyncDrawable;
import ru.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.DefaultMediaDecoder;
import ru.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImageItem;
import ru.noties.markwon.image.gif.GifPlugin; import io.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin; import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
/** /**
* Author M M Arif * Author M M Arif
@ -116,8 +125,45 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.createWithAssets(mCtx)) @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() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
@ -130,11 +176,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
.usePlugin(TablePlugin.create(mCtx)) .usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx)) .usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build(); .build();
holder.msTitle.setText(currentItem.getTitle()); Spanned msTitle = markwon.toMarkdown(currentItem.getTitle());
markwon.setParsedMarkdown(holder.msTitle, msTitle);
//holder.msStatus.setText(currentItem.getState()); //holder.msStatus.setText(currentItem.getState());
if(currentItem.getState().equals("open")) { if(currentItem.getState().equals("open")) {

View File

@ -1,8 +1,10 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Html; import android.text.Html;
import android.text.Spanned;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -13,22 +15,30 @@ import com.amulyakhare.textdrawable.TextDrawable;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.models.Releases; import org.mian.gitnex.models.Releases;
import org.mian.gitnex.util.TinyDB;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon;
import ru.noties.markwon.Markwon; import io.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.CorePlugin; import io.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.AsyncDrawable;
import ru.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.DefaultMediaDecoder;
import ru.noties.markwon.image.gif.GifPlugin; import io.noties.markwon.image.ImageItem;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
/** /**
* Author M M Arif * Author M M Arif
@ -77,6 +87,8 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@Override @Override
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) { public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(mCtx);
Releases currentItem = releasesList.get(position); Releases currentItem = releasesList.get(position);
holder.releaseTitle.setText(currentItem.getName()); holder.releaseTitle.setText(currentItem.getName());
@ -115,28 +127,65 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.createWithAssets(mCtx)) @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() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder builder
.codeTextColor(Color.GREEN) .codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(Color.BLACK) .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue)); .linkColor(mCtx.getResources().getColor(R.color.lightBlue));
} }
}) })
.usePlugin(TablePlugin.create(mCtx)) .usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx)) .usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build(); .build();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody())); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody()));
if(!currentItem.getBody().equals("")) { if(!currentItem.getBody().equals("")) {
holder.releaseDescription.setText(bodyWithMD); markwon.setParsedMarkdown(holder.releaseDescription, bodyWithMD);
} }
else { else {
holder.releaseDescription.setVisibility(View.GONE); holder.releaseDescription.setVisibility(View.GONE);

View File

@ -1,24 +1,31 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import ru.noties.markwon.AbstractMarkwonPlugin; import android.text.Spanned;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -40,6 +47,8 @@ import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@ -299,30 +308,68 @@ public class RepoInfoFragment extends Fragment {
if (response.code() == 200) { if (response.code() == 200) {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext())) final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.createWithAssets(getContext())) @Override
.usePlugin(new AbstractMarkwonPlugin() { public void configureImages(@NonNull ImagesPlugin plugin) {
@Override plugin.addSchemeHandler(new SchemeHandler() {
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { @NonNull
builder @Override
.codeTextColor(tinyDb.getInt("codeBlockColor")) public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
CharSequence bodyWithMD = null; final int resourceId = getContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getContext().getPackageName());
final Drawable drawable = getContext().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(getContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getContext().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(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
Spanned bodyWithMD = null;
if (response.body() != null) { if (response.body() != null) {
bodyWithMD = markwon.toMarkdown(response.body()); bodyWithMD = markwon.toMarkdown(response.body());
} }
repoFileContents.setText(bodyWithMD); assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
} else if (response.code() == 401) { } else if (response.code() == 401) {

View File

@ -0,0 +1,5 @@
<vector android:height="16dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18z"/>
</vector>

Binary file not shown.

View File

@ -1,119 +1,109 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayoutFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_margin="15dp"
android:id="@+id/relativeLayoutMainFrame" android:theme="@style/AppTheme"
android:background="@color/backgroundColor"> tools:context=".activities.RepoDetailActivity">
<RelativeLayout <TextView
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/issueNumber"
android:id="@+id/relativeLayoutFrame" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_android" />
<LinearLayout
android:id="@+id/infoSection"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_margin="15dp" android:layout_toEndOf="@+id/assigneeAvatar"
android:theme="@style/AppTheme" android:orientation="vertical">
tools:context=".activities.RepoDetailActivity">
<TextView
android:id="@+id/issueNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="15dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_android" />
<TextView
android:layout_marginTop="10dp"
android:id="@+id/issueCommentsCount"
android:layout_width="48dp"
android:layout_height="50dp"
android:width="16dp"
android:height="16dp"
android:layout_marginEnd="15dp"
android:layout_below="@+id/assigneeAvatar"
android:drawableTop="@drawable/ic_comment"
android:gravity="center"
android:textColor="@color/colorWhite"
android:textSize="14sp" />
<LinearLayout <LinearLayout
android:id="@+id/infoSection" android:id="@+id/frameIssueNameStatus"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toEndOf="@+id/assigneeAvatar" android:layout_marginBottom="10dp"
android:orientation="vertical"> android:orientation="horizontal">
<TextView
android:id="@+id/issueTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".65"
android:gravity="top|center_vertical"
android:textAlignment="gravity"
android:text="@string/strFilter"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:layout_width="0dp"
android:layout_weight=".08"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/issueType"
android:layout_width="16dp"
android:layout_height="21dp"
android:layout_marginTop="5dp"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_issues" />
</LinearLayout>
<LinearLayout
android:id="@+id/frameCreatedDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<LinearLayout <LinearLayout
android:id="@+id/frameIssueNameStatus" android:id="@+id/frameCommentsCount"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/issueTitle" android:id="@+id/issueCommentsCount"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_weight=".82"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:gravity="start"
android:textSize="18sp" /> android:drawablePadding="5dp"
android:drawableStart="@drawable/ic_comment_16"
<TextView
android:layout_width="0dp"
android:layout_weight=".08"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/issueType"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:contentDescription="@string/generalImgContentText" android:textColor="@color/colorWhite"
android:src="@drawable/ic_issues" /> android:textSize="12sp" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/issueDescription" android:id="@+id/issueCreatedTime"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10dp" android:gravity="end"
android:textColor="@color/colorWhite" android:textColor="@color/colorWhite"
android:textSize="16sp" android:textSize="12sp" />
android:visibility="gone" />
<LinearLayout
android:id="@+id/frameCreatedDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/issueCreatedAtText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/createdText"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
<TextView
android:id="@+id/issueCreatedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -32,6 +32,7 @@
<string name="pageTitleStarredRepos">Favoriten</string> <string name="pageTitleStarredRepos">Favoriten</string>
<string name="pageTitleCreateTeam">Team erstellen</string> <string name="pageTitleCreateTeam">Team erstellen</string>
<string name="pageTitleAddEmail">E-Mail Adresse hinzufügen</string> <string name="pageTitleAddEmail">E-Mail Adresse hinzufügen</string>
<string name="pageTitleNewFile">New File</string>
<!-- page titles --> <!-- page titles -->
<string name="appVersion">Version\u0020:\u0020</string> <string name="appVersion">Version\u0020:\u0020</string>

View File

@ -33,6 +33,7 @@
<string name="pageTitleStarredRepos">Starred Repositories</string> <string name="pageTitleStarredRepos">Starred Repositories</string>
<string name="pageTitleCreateTeam">Create Team</string> <string name="pageTitleCreateTeam">Create Team</string>
<string name="pageTitleAddEmail">Add Email Address</string> <string name="pageTitleAddEmail">Add Email Address</string>
<string name="pageTitleNewFile">New File</string>
<!-- page titles --> <!-- page titles -->
<string name="appVersion">Version\u0020:\u0020</string> <string name="appVersion">Version\u0020:\u0020</string>

View File

@ -33,6 +33,7 @@
<string name="pageTitleStarredRepos">Избранные репозитории</string> <string name="pageTitleStarredRepos">Избранные репозитории</string>
<string name="pageTitleCreateTeam">Создать команду</string> <string name="pageTitleCreateTeam">Создать команду</string>
<string name="pageTitleAddEmail">Добавить адрес эл. почты</string> <string name="pageTitleAddEmail">Добавить адрес эл. почты</string>
<string name="pageTitleNewFile">New File</string>
<!-- page titles --> <!-- page titles -->
<string name="appVersion">Версия\u0020:\u0020</string> <string name="appVersion">Версия\u0020:\u0020</string>

View File

@ -5,7 +5,7 @@
<item name="android:statusBarColor">@color/colorPrimary</item> <item name="android:statusBarColor">@color/colorPrimary</item>
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="android:fontFamily">@font/sourcecodeproregular</item> <item name="android:fontFamily">@font/roboto</item>
<item name="android:windowBackground">@color/colorPrimary</item> <item name="android:windowBackground">@color/colorPrimary</item>
</style> </style>

View File

@ -161,7 +161,7 @@
<string name="timeAtText">at</string> <string name="timeAtText">at</string>
<string name="hash">#</string> <string name="hash">#</string>
<string name="createdText">Created\u0020</string> <string name="createdText">Opened\u0020</string>
<string name="dueDateText">Due Date</string> <string name="dueDateText">Due Date</string>
<string name="issueStatusTextOpen">Status: open</string> <string name="issueStatusTextOpen">Status: open</string>
<string name="issueStatusOpen">open</string> <string name="issueStatusOpen">open</string>
@ -175,7 +175,7 @@
<string name="issueTitleWithId">#%1$d %2$s</string> <string name="issueTitleWithId">#%1$d %2$s</string>
<string name="issueMilestone">Milestone %1$s</string> <string name="issueMilestone">Milestone %1$s</string>
<string name="dueDate">Due %1$s</string> <string name="dueDate">Due %1$s</string>
<string name="createdTime">Created %1$s</string> <string name="createdTime">Opened %1$s</string>
<string name="assignedTo">Assigned to: %1$s</string> <string name="assignedTo">Assigned to: %1$s</string>
<string name="commentButtonText">Comment</string> <string name="commentButtonText">Comment</string>
<string name="commentEmptyError">Please write your comment</string> <string name="commentEmptyError">Please write your comment</string>

View File

@ -4,7 +4,7 @@
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="android:fontFamily">@font/sourcecodeproregular</item> <item name="android:fontFamily">@font/roboto</item>
<item name="drawerArrowStyle">@style/DrawerIcon</item> <item name="drawerArrowStyle">@style/DrawerIcon</item>
<item name="colorControlHighlight">#123456</item> <item name="colorControlHighlight">#123456</item>
</style> </style>