mirror of
https://codeberg.org/gitnex/GitNex.git
synced 2023-12-13 20:50:18 +01:00
9d3cd49d23
clean up Another round of ui improvements and some refactors Minor improvements. Hide user accounts frame while list is loading Remove unnecessary attribute Minor improvements. Define avatar size in lists globally. Improvemnts to some ui elements Improve layout of organizations and repositories. Update the UI across most of the screens Refactor org UI clean up repo layout Add archived msg instead of label Redesign repos UI Move archived to repo detail screen Co-authored-by: M M Arif <mmarif@swatian.com> Co-authored-by: opyale <opyale@noreply.codeberg.org> Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/894 Reviewed-by: opyale <opyale@noreply.codeberg.org> Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org> Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
178 lines
5.2 KiB
Java
178 lines
5.2 KiB
Java
package org.mian.gitnex.helpers;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Typeface;
|
|
import android.text.Spanned;
|
|
import android.widget.TextView;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.core.content.res.ResourcesCompat;
|
|
import org.mian.gitnex.R;
|
|
import org.mian.gitnex.clients.PicassoService;
|
|
import org.mian.gitnex.core.MainGrammarLocator;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.SynchronousQueue;
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
import java.util.concurrent.TimeUnit;
|
|
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.picasso.PicassoImagesPlugin;
|
|
import io.noties.markwon.linkify.LinkifyPlugin;
|
|
import io.noties.markwon.syntax.Prism4jTheme;
|
|
import io.noties.markwon.syntax.Prism4jThemeDarkula;
|
|
import io.noties.markwon.syntax.Prism4jThemeDefault;
|
|
import io.noties.markwon.syntax.SyntaxHighlightPlugin;
|
|
import io.noties.prism4j.Prism4j;
|
|
import stormpot.Allocator;
|
|
import stormpot.BlazePool;
|
|
import stormpot.Config;
|
|
import stormpot.Pool;
|
|
import stormpot.Poolable;
|
|
import stormpot.Slot;
|
|
import stormpot.Timeout;
|
|
|
|
/**
|
|
* @author opyale
|
|
*/
|
|
|
|
public class Markdown {
|
|
|
|
private static final int MAX_POOL_SIZE = 45;
|
|
private static final int MAX_THREAD_KEEP_ALIVE_SECONDS = 120;
|
|
private static final int MAX_CLAIM_TIMEOUT_SECONDS = 120;
|
|
|
|
private static final Timeout timeout = new Timeout(MAX_CLAIM_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
|
|
|
private static final ExecutorService executorService =
|
|
new ThreadPoolExecutor(MAX_POOL_SIZE / 2, MAX_POOL_SIZE, MAX_THREAD_KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<>());
|
|
|
|
private static final Pool<Renderer> rendererPool;
|
|
|
|
static {
|
|
|
|
Config<Renderer> config = new Config<>();
|
|
|
|
config.setBackgroundExpirationEnabled(true);
|
|
config.setPreciseLeakDetectionEnabled(true);
|
|
config.setSize(MAX_POOL_SIZE);
|
|
config.setAllocator(new Allocator<Renderer>() {
|
|
|
|
@Override
|
|
public Renderer allocate(Slot slot) throws Exception {
|
|
return new Renderer(slot);
|
|
}
|
|
|
|
@Override public void deallocate(Renderer poolable) throws Exception {}
|
|
|
|
});
|
|
|
|
rendererPool = new BlazePool<>(config);
|
|
|
|
}
|
|
|
|
public static void render(Context context, String markdown, TextView textView) {
|
|
|
|
try {
|
|
Renderer renderer = rendererPool.claim(timeout);
|
|
|
|
if(renderer != null) {
|
|
renderer.setParameters(context, markdown, textView);
|
|
executorService.execute(renderer);
|
|
}
|
|
} catch(InterruptedException ignored) {}
|
|
}
|
|
|
|
private static class Renderer implements Runnable, Poolable {
|
|
|
|
private final Slot slot;
|
|
|
|
private Markwon markwon;
|
|
|
|
private Context context;
|
|
private String markdown;
|
|
private TextView textView;
|
|
|
|
public Renderer(Slot slot) {
|
|
this.slot = slot;
|
|
}
|
|
|
|
private void setup() {
|
|
|
|
Prism4jTheme prism4jTheme = TinyDB.getInstance(context).getString("currentTheme").equals("dark") ?
|
|
Prism4jThemeDarkula.create() :
|
|
Prism4jThemeDefault.create();
|
|
|
|
Markwon.Builder builder = Markwon.builder(context)
|
|
.usePlugin(CorePlugin.create())
|
|
.usePlugin(HtmlPlugin.create())
|
|
.usePlugin(LinkifyPlugin.create(true))
|
|
.usePlugin(TablePlugin.create(context))
|
|
.usePlugin(TaskListPlugin.create(context))
|
|
.usePlugin(StrikethroughPlugin.create())
|
|
.usePlugin(PicassoImagesPlugin.create(PicassoService.getInstance(context).get()))
|
|
.usePlugin(SyntaxHighlightPlugin.create(new Prism4j(MainGrammarLocator.getInstance()), prism4jTheme, MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE))
|
|
.usePlugin(new AbstractMarkwonPlugin() {
|
|
|
|
@Override
|
|
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
|
builder.codeBlockTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
|
|
builder.codeBlockMargin((int) (context.getResources().getDisplayMetrics().density * 10));
|
|
builder.blockMargin((int) (context.getResources().getDisplayMetrics().density * 10));
|
|
builder.codeTextSize((int) (context.getResources().getDisplayMetrics().scaledDensity * 13));
|
|
builder.codeTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
|
|
builder.linkColor(ResourcesCompat.getColor(context.getResources(), R.color.lightBlue, null));
|
|
}
|
|
});
|
|
|
|
markwon = builder.build();
|
|
|
|
}
|
|
|
|
public void setParameters(Context context, String markdown, TextView textView) {
|
|
|
|
this.context = context;
|
|
this.markdown = markdown;
|
|
this.textView = textView;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
|
|
Objects.requireNonNull(context);
|
|
Objects.requireNonNull(markdown);
|
|
Objects.requireNonNull(textView);
|
|
|
|
if(markwon == null) setup();
|
|
|
|
Spanned processedMarkdown = markwon.toMarkdown(markdown);
|
|
|
|
TextView localReference = textView;
|
|
localReference.post(() -> localReference.setText(processedMarkdown));
|
|
|
|
release();
|
|
|
|
}
|
|
|
|
@Override
|
|
public void release() {
|
|
|
|
context = null;
|
|
markdown = null;
|
|
textView = null;
|
|
|
|
slot.release(this);
|
|
|
|
}
|
|
|
|
public void expire() {
|
|
slot.expire(this);
|
|
}
|
|
}
|
|
}
|