diff --git a/app/build.gradle b/app/build.gradle index faa99c29..7face7c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { } dependencies { - def lifecycle_version = "2.2.0-alpha04" - final def markwon_version = "3.0.0" + def lifecycle_version = "2.2.0-alpha05" + final def markwon_version = "4.1.1" implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.1.0' @@ -47,17 +47,21 @@ dependencies { implementation "com.vdurmont:emoji-java:4.0.0" implementation "com.pes.materialcolorpicker:library:1.2.5" - implementation "ru.noties.markwon:core:$markwon_version" - implementation "ru.noties.markwon:ext-strikethrough:$markwon_version" - implementation "ru.noties.markwon:ext-tables:$markwon_version" - implementation "ru.noties.markwon:ext-tasklist:$markwon_version" - implementation "ru.noties.markwon:syntax-highlight:$markwon_version" - implementation "ru.noties.markwon:image-okhttp:$markwon_version" - implementation "ru.noties.markwon:html:$markwon_version" - implementation "ru.noties.markwon:recycler:$markwon_version" - implementation "ru.noties.markwon:recycler-table:$markwon_version" - implementation "ru.noties.markwon:image-gif:$markwon_version" - implementation "ru.noties.markwon:image-svg:$markwon_version" + implementation "io.noties.markwon:core:$markwon_version" + implementation "io.noties.markwon:ext-latex:$markwon_version" + implementation "io.noties.markwon:ext-strikethrough:$markwon_version" + implementation "io.noties.markwon:ext-tables:$markwon_version" + implementation "io.noties.markwon:ext-tasklist:$markwon_version" + implementation "io.noties.markwon:html:$markwon_version" + implementation "io.noties.markwon:image:$markwon_version" + implementation "io.noties.markwon:image-picasso:$markwon_version" + implementation "io.noties.markwon:linkify:$markwon_version" + implementation "io.noties.markwon:recycler:$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-commons:0.2" diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java index d24294f4..e7962d46 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -10,26 +10,33 @@ import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; 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.Callback; 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.graphics.Color; import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.text.Spanned; import android.util.Log; import android.view.Gravity; import android.view.Menu; @@ -63,6 +70,8 @@ import org.mian.gitnex.viewmodels.IssueCommentsViewModel; import org.ocpsoft.prettytime.PrettyTime; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -286,22 +295,60 @@ public class IssueDetailActivity extends AppCompatActivity { final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext())) .usePlugin(CorePlugin.create()) - .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) - .usePlugin(ImagesPlugin.createWithAssets(getApplicationContext())) + .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 = 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 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() { @Override public void configureTheme(@NonNull MarkwonTheme.Builder builder) { builder .codeTextColor(tinyDb.getInt("codeBlockColor")) .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(getApplicationContext().getResources().getColor(R.color.lightBlue)); + .linkColor(getResources().getColor(R.color.lightBlue)); } }) .usePlugin(TablePlugin.create(getApplicationContext())) .usePlugin(TaskListPlugin.create(getApplicationContext())) .usePlugin(HtmlPlugin.create()) - .usePlugin(GifPlugin.create()) .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create()) .build(); 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); issueTitle.setText(getString(R.string.issueTitleWithId, singleIssue.getNumber(), singleIssue.getTitle())); String cleanIssueDescription = singleIssue.getBody().trim(); - final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); - issueDescription.setText(UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription)); + Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); + markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription)); RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams(); diff --git a/app/src/main/java/org/mian/gitnex/adapters/ClosedIssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ClosedIssuesAdapter.java index e9c94182..19d7a05a 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/ClosedIssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/ClosedIssuesAdapter.java @@ -3,22 +3,21 @@ package org.mian.gitnex.adapters; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.graphics.Color; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.squareup.picasso.Picasso; -import com.vdurmont.emoji.EmojiParser; import org.mian.gitnex.R; import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.models.Issues; import org.mian.gitnex.util.TinyDB; import org.ocpsoft.prettytime.PrettyTime; @@ -27,22 +26,8 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.Objects; import androidx.annotation.NonNull; 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 @@ -122,8 +107,6 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + ""; + issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle())); + issueNumber.setText(String.valueOf(issuesModel.getNumber())); 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) { case "pretty": { PrettyTime prettyTime = new PrettyTime(new Locale(locale)); diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java index 04f4da17..02088f1e 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java @@ -3,7 +3,9 @@ package org.mian.gitnex.adapters; import android.annotation.SuppressLint; import android.content.Context; 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.MenuItem; import android.view.View; @@ -14,7 +16,6 @@ import com.squareup.picasso.Picasso; import com.vdurmont.emoji.EmojiParser; import org.mian.gitnex.R; import org.mian.gitnex.activities.ReplyToIssueActivity; -import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.helpers.RoundedTransformation; @@ -24,26 +25,32 @@ import org.ocpsoft.prettytime.PrettyTime; import java.lang.reflect.Field; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.widget.PopupMenu; 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; +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; /** * Author M M Arif @@ -180,25 +187,63 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter 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")); + .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) + .linkColor(mCtx.getResources().getColor(R.color.lightBlue)); } }) .usePlugin(TablePlugin.create(mCtx)) .usePlugin(TaskListPlugin.create(mCtx)) .usePlugin(HtmlPlugin.create()) - .usePlugin(GifPlugin.create()) .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create()) .build(); - final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments)); - holder.issueComment.setText(UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments)); + Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments)); + markwon.setParsedMarkdown(holder.issueComment, bodyWithMD); String edited; diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java index 645b80f4..5e6a8960 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java @@ -3,22 +3,21 @@ package org.mian.gitnex.adapters; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.graphics.Color; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.squareup.picasso.Picasso; -import com.vdurmont.emoji.EmojiParser; import org.mian.gitnex.R; import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.models.Issues; import org.mian.gitnex.util.TinyDB; import org.ocpsoft.prettytime.PrettyTime; @@ -27,22 +26,8 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.Objects; import androidx.annotation.NonNull; 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 @@ -122,8 +107,6 @@ public class IssuesAdapter extends RecyclerView.Adapter private TextView issueNumber; private ImageView issueAssigneeAvatar; private TextView issueTitle; - private TextView issueDescription; - //private ImageView issueState; private TextView issueCreatedTime; private TextView issueCommentsCount; private ImageView issueType; @@ -135,9 +118,8 @@ public class IssuesAdapter extends RecyclerView.Adapter issueNumber = itemView.findViewById(R.id.issueNumber); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueTitle = itemView.findViewById(R.id.issueTitle); - issueDescription = itemView.findViewById(R.id.issueDescription); 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); issueType = itemView.findViewById(R.id.issueType); @@ -157,7 +139,7 @@ public class IssuesAdapter extends RecyclerView.Adapter } }); - issueDescription.setOnClickListener(new View.OnClickListener() { + frameCommentsCount.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -183,26 +165,6 @@ public class IssuesAdapter extends RecyclerView.Adapter final String locale = tinyDb.getString("locale"); 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("")) { issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context)); } else { @@ -210,9 +172,9 @@ public class IssuesAdapter extends RecyclerView.Adapter } 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 { - 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) { @@ -223,28 +185,12 @@ public class IssuesAdapter extends RecyclerView.Adapter 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_ = "" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + ""; + issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle())); + issueNumber.setText(String.valueOf(issuesModel.getNumber())); 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) { case "pretty": { PrettyTime prettyTime = new PrettyTime(new Locale(locale)); diff --git a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java index 5690094f..dff16ecc 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java @@ -3,6 +3,9 @@ package org.mian.gitnex.adapters; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -22,25 +25,31 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Objects; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; 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; +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; /** * Author M M Arif @@ -116,8 +125,45 @@ public class MilestonesAdapter extends RecyclerView.Adapter 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) { @@ -130,11 +176,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter 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(Color.GREEN) - .codeBackgroundColor(Color.BLACK) + .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(GifPlugin.create()) .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create()) .build(); - final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody())); + Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody())); if(!currentItem.getBody().equals("")) { - holder.releaseDescription.setText(bodyWithMD); + markwon.setParsedMarkdown(holder.releaseDescription, bodyWithMD); } else { holder.releaseDescription.setVisibility(View.GONE); diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java index 7bbac01e..59067193 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java @@ -1,24 +1,31 @@ package org.mian.gitnex.fragments; import android.content.Context; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; 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.Callback; -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.text.Spanned; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -40,6 +47,8 @@ import org.mian.gitnex.util.TinyDB; import org.ocpsoft.prettytime.PrettyTime; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; import java.util.Locale; import java.util.Objects; @@ -299,30 +308,68 @@ public class RepoInfoFragment extends Fragment { if (response.code() == 200) { final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext())) - .usePlugin(CorePlugin.create()) - .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) - .usePlugin(ImagesPlugin.createWithAssets(getContext())) - .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(GifPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .build(); + .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) { - 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 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) { bodyWithMD = markwon.toMarkdown(response.body()); } - repoFileContents.setText(bodyWithMD); + assert bodyWithMD != null; + markwon.setParsedMarkdown(repoFileContents, bodyWithMD); } else if (response.code() == 401) { diff --git a/app/src/main/res/drawable/ic_comment_16.xml b/app/src/main/res/drawable/ic_comment_16.xml new file mode 100644 index 00000000..186a57d7 --- /dev/null +++ b/app/src/main/res/drawable/ic_comment_16.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/font/opensanssemibold.ttf b/app/src/main/res/font/opensanssemibold.ttf deleted file mode 100644 index 99db86aa..00000000 Binary files a/app/src/main/res/font/opensanssemibold.ttf and /dev/null differ diff --git a/app/src/main/res/font/roboto.ttf b/app/src/main/res/font/roboto.ttf new file mode 100644 index 00000000..2b6392ff Binary files /dev/null and b/app/src/main/res/font/roboto.ttf differ diff --git a/app/src/main/res/layout/repo_detail_issues_list.xml b/app/src/main/res/layout/repo_detail_issues_list.xml index d5048866..a2687dae 100644 --- a/app/src/main/res/layout/repo_detail_issues_list.xml +++ b/app/src/main/res/layout/repo_detail_issues_list.xml @@ -1,119 +1,109 @@ - + android:layout_margin="15dp" + android:theme="@style/AppTheme" + tools:context=".activities.RepoDetailActivity"> - + + + + - - - - - - + android:layout_height="wrap_content" + android:layout_toEndOf="@+id/assigneeAvatar" + android:orientation="vertical"> + android:layout_marginBottom="10dp" + android:orientation="horizontal"> + + + + + + + + + + - - - - + android:textColor="@color/colorWhite" + android:textSize="12sp" /> - - - - - - - - + android:textSize="12sp" /> - + - + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1ff88203..f36475a1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -32,6 +32,7 @@ Favoriten Team erstellen E-Mail Adresse hinzufügen + New File Version\u0020:\u0020 diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6bf7f7d1..54c4d67d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -33,6 +33,7 @@ Starred Repositories Create Team Add Email Address + New File Version\u0020:\u0020 diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ea69029d..48f47a57 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -33,6 +33,7 @@ Избранные репозитории Создать команду Добавить адрес эл. почты + New File Версия\u0020:\u0020 diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index c1335fe6..3d46f876 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -5,7 +5,7 @@ @color/colorPrimary @color/colorPrimary @color/colorPrimary - @font/sourcecodeproregular + @font/roboto @color/colorPrimary diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4a24ed37..6b0d669a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -161,7 +161,7 @@ at # - Created\u0020 + Opened\u0020 Due Date Status: open open @@ -175,7 +175,7 @@ #%1$d %2$s Milestone %1$s Due %1$s - Created %1$s + Opened %1$s Assigned to: %1$s Comment Please write your comment diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ab9a81e4..2fa70ea1 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -4,7 +4,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent - @font/sourcecodeproregular + @font/roboto @style/DrawerIcon #123456