Md support in file viewer (#607)

format

implement support for md on tap on icon

show icon for md files only

Add md to top bar

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/607
Reviewed-by: 6543 <6543@noreply.codeberg.org>
This commit is contained in:
M M Arif 2020-07-29 20:45:05 +02:00 committed by 6543
parent 73e7acfbdf
commit f1ecc42876
4 changed files with 123 additions and 12 deletions

View File

@ -8,6 +8,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.Spanned;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
@ -42,7 +43,24 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects; import java.util.Objects;
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.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;
@ -65,6 +83,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private LinearLayout pdfViewFrame; private LinearLayout pdfViewFrame;
private byte[] decodedPdf; private byte[] decodedPdf;
private Boolean pdfNightMode; private Boolean pdfNightMode;
private String singleFileName;
private AppUtil appUtil;
private TinyDB tinyDb;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -77,11 +98,12 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
appUtil = new AppUtil();
tinyDb = new TinyDB(appCtx);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String repoBranch = tinyDb.getString("repoBranch"); String repoBranch = tinyDb.getString("repoBranch");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -91,6 +113,8 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
tinyDb.putBoolean("enableMarkdownInFileView", false);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents); singleFileContents = findViewById(R.id.singleFileContents);
singleCodeContents = findViewById(R.id.singleCodeContents); singleCodeContents = findViewById(R.id.singleCodeContents);
@ -100,7 +124,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
pdfViewFrame = findViewById(R.id.pdfViewFrame); pdfViewFrame = findViewById(R.id.pdfViewFrame);
singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame); singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame);
String singleFileName = getIntent().getStringExtra("singleFileName"); singleFileName = getIntent().getStringExtra("singleFileName");
TextView toolbar_title = findViewById(R.id.toolbar_title); TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod()); toolbar_title.setMovementMethod(new ScrollingMovementMethod());
@ -119,7 +143,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
catch(UnsupportedEncodingException e) { catch(UnsupportedEncodingException e) {
assert singleFileName != null;
Log.i("singleFileName", singleFileName); Log.i("singleFileName", singleFileName);
} }
@ -132,8 +155,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) { private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref); Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref);
call.enqueue(new Callback<Files>() { call.enqueue(new Callback<Files>() {
@ -143,7 +164,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(response.code() == 200) { if(response.code() == 200) {
AppUtil appUtil = new AppUtil();
assert response.body() != null; assert response.body() != null;
if(!response.body().getContent().equals("")) { if(!response.body().getContent().equals("")) {
@ -277,6 +297,13 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
inflater.inflate(R.menu.files_view_menu, menu);
String fileExtension = FileUtils.getExtension(singleFileName);
if(!fileExtension.equalsIgnoreCase("md")) {
menu.getItem(0).setVisible(false);
}
return true; return true;
} }
@ -287,11 +314,82 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
switch(id) { switch(id) {
case android.R.id.home: case android.R.id.home:
finish(); finish();
return true; return true;
case R.id.genericMenu: case R.id.genericMenu:
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment(); BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
return true;
case R.id.markdown:
final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = ctx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
ctx.getPackageName());
final Drawable drawable = ctx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(ctx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(ctx.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(ctx))
.usePlugin(TaskListPlugin.create(ctx))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
if(!tinyDb.getBoolean("enableMarkdownInFileView")) {
singleCodeContents.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setVisibility(View.VISIBLE);
Spanned bodyWithMD = markwon.toMarkdown(appUtil.decodeBase64(tinyDb.getString("downloadFileContents")));
markwon.setParsedMarkdown(singleFileContents, bodyWithMD);
tinyDb.putBoolean("enableMarkdownInFileView", true);
}
else {
singleCodeContents.setVisibility(View.VISIBLE);
singleFileContentsFrame.setVisibility(View.GONE);
singleFileContents.setVisibility(View.GONE);
singleCodeContents.setSource(appUtil.decodeBase64(tinyDb.getString("downloadFileContents")));
tinyDb.putBoolean("enableMarkdownInFileView", false);
}
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -312,8 +410,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private void requestFileDownload() { private void requestFileDownload() {
final TinyDB tinyDb = new TinyDB(appCtx);
if(!tinyDb.getString("downloadFileContents").isEmpty()) { if(!tinyDb.getString("downloadFileContents").isEmpty()) {
int CREATE_REQUEST_CODE = 40; int CREATE_REQUEST_CODE = 40;
@ -340,9 +436,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
final TinyDB tinyDb = new TinyDB(appCtx); if(requestCode == 40 && resultCode == RESULT_OK) {
if (requestCode == 40 && resultCode == RESULT_OK) {
try { try {
@ -361,7 +455,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
Toasty.info(ctx, getString(R.string.downloadFileSaved)); Toasty.info(ctx, getString(R.string.downloadFileSaved));
} }
catch (IOException e) { catch(IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
} }

View File

@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="16"
android:viewportWidth="16" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#368f73" android:fillType="evenOdd" android:pathData="M14.85,3L1.15,3C0.52,3 0,3.52 0,4.15v7.69C0,12.48 0.52,13 1.15,13h13.69c0.64,0 1.15,-0.52 1.15,-1.15v-7.7C16,3.52 15.48,3 14.85,3zM9,11L7,11L7,8L5.5,9.92 4,8v3L2,11L2,5h2l1.5,2L7,5h2v6zM11.99,11.5L9.5,8L11,8L11,5h2v3h1.5l-2.51,3.5z"/>
</vector>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/markdown"
android:icon="@drawable/ic_markdown"
android:title="@string/strMarkdown"
android:orderInCategory="0"
app:showAsAction="ifRoom" />
</menu>

View File

@ -465,6 +465,7 @@
<string name="strFilter">Filter</string> <string name="strFilter">Filter</string>
<string name="strSwitchBranches">Branches</string> <string name="strSwitchBranches">Branches</string>
<string name="strMarkdown">Markdown</string>
<string name="copyIssueUrl">Copy Issue URL</string> <string name="copyIssueUrl">Copy Issue URL</string>
<string name="copyIssueUrlToastMsg">URL copied to clipboard</string> <string name="copyIssueUrlToastMsg">URL copied to clipboard</string>