Fix scrolling for code blocks and clean up warnings

This commit is contained in:
William Brawner 2018-01-27 19:24:54 -06:00 committed by William Brawner
parent f82330a92f
commit 731377a420
14 changed files with 257 additions and 237 deletions

View file

@ -4,10 +4,6 @@ import android.app.Application;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
/**
* Created by billy on 8/22/17.
*/
public class MarkdownApplication extends Application { public class MarkdownApplication extends Application {
private AppComponent component; private AppComponent component;

View file

@ -7,8 +7,10 @@ import android.preference.PreferenceManager;
import com.wbrawner.simplemarkdown.view.activity.SettingsActivity; import com.wbrawner.simplemarkdown.view.activity.SettingsActivity;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -75,4 +77,13 @@ public class Utils {
); );
} }
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

View file

@ -1,39 +1,23 @@
package com.wbrawner.simplemarkdown.model; package com.wbrawner.simplemarkdown.model;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.Locale;
import java.util.Scanner; import java.util.Scanner;
import static android.content.ContentValues.TAG;
/** /**
* This class serves as a wrapper to manage the manage the file input and output operations, as well * This class serves as a wrapper to manage the manage the file input and output operations, as well
* as to keep track of the data itself in memory. * as to keep track of the data itself in memory.
*/ */
public class MarkdownFile { public class MarkdownFile {
public static final int SUCCESS = 0;
public static final int FILE_EXISTS = 1;
public static final int FILE_NOT_EXISTS = 2;
public static final int READ_ERROR = 3;
public static final int WRITE_ERROR = 4;
public static final int PARAMETERS_MISSING = 5;
public static void setDefaultRootDir(String defaultRootDir) {
MarkdownFile.defaultRootDir = defaultRootDir;
}
private static String defaultRootDir = ""; private static String defaultRootDir = "";
private String name; private String name;
private String path; private String path;
private String content; private String content;
public MarkdownFile(String name, String path, String content) { public MarkdownFile(String name, String path, String content) {
this.name = name; this.name = name;
if (path == null || path.isEmpty()) { if (path == null || path.isEmpty()) {
@ -44,8 +28,7 @@ public class MarkdownFile {
} }
public MarkdownFile(String path) { public MarkdownFile(String path) {
int code = load(path); if (load(path)) {
if (code != SUCCESS) {
this.name = path.substring( this.name = path.substring(
path.lastIndexOf("/") + 1 path.lastIndexOf("/") + 1
); );
@ -63,6 +46,10 @@ public class MarkdownFile {
this.content = ""; this.content = "";
} }
public static void setDefaultRootDir(String defaultRootDir) {
MarkdownFile.defaultRootDir = defaultRootDir;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -75,6 +62,10 @@ public class MarkdownFile {
return path; return path;
} }
public void setPath(String path) {
this.path = path;
}
public String getFullPath() { public String getFullPath() {
String fullPath; String fullPath;
@ -95,10 +86,6 @@ public class MarkdownFile {
return fullPath + this.name; return fullPath + this.name;
} }
public void setPath(String path) {
this.path = path;
}
public String getContent() { public String getContent() {
return content; return content;
} }
@ -107,61 +94,46 @@ public class MarkdownFile {
this.content = content; this.content = content;
} }
public int load(InputStream in) { public boolean load(InputStream in) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Scanner s = new java.util.Scanner(in).useDelimiter("\\n"); Scanner s = new java.util.Scanner(in).useDelimiter("\\n");
if (s == null) {
return false;
}
while (s.hasNext()) { while (s.hasNext()) {
sb.append(s.next() + "\n"); sb.append(s.next()).append("\n");
} }
this.content = sb.toString(); this.content = sb.toString();
return SUCCESS; try {
in.close();
} catch (Exception ignored) {
}
return true;
} }
public int load(String path) { private boolean load(String path) {
return load(new File(path)); return load(new File(path));
} }
public int load(File markdownFile) { private boolean load(File markdownFile) {
int code; if (!markdownFile.exists() || !markdownFile.canRead()) {
if (markdownFile.exists() && markdownFile.canRead()) { return false;
BufferedReader reader = null; }
try {
this.name = markdownFile.getName(); try {
this.path = markdownFile.getParentFile().getAbsolutePath(); this.name = markdownFile.getName();
this.path = markdownFile.getParentFile().getAbsolutePath();
StringBuilder sb = new StringBuilder(); return load(new FileInputStream(markdownFile));
String line; } catch (FileNotFoundException e) {
reader = new BufferedReader(new FileReader(markdownFile)); return false;
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
this.content = sb.toString();
code = SUCCESS;
} catch (FileNotFoundException e) {
code = FILE_NOT_EXISTS;
} catch (IOException e) {
code = READ_ERROR;
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// closing the reader failed
}
}
} else {
code = READ_ERROR;
} }
return code;
} }
public int load() { public boolean load() {
if (this.name.isEmpty()) return !this.name.isEmpty() && load(getFullPath());
return PARAMETERS_MISSING;
return load(getFullPath());
} }
public int save(String path) { public boolean save(String path) {
int code;
if (path == null) { if (path == null) {
path = this.getFullPath(); path = this.getFullPath();
} }
@ -169,23 +141,28 @@ public class MarkdownFile {
File markdownFile = new File(path); File markdownFile = new File(path);
if (!markdownFile.exists()) { if (!markdownFile.exists()) {
try { try {
markdownFile.createNewFile(); if (!markdownFile.createNewFile()) {
return false;
}
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return WRITE_ERROR; return false;
} }
} }
if (markdownFile.canWrite()) {
OutputStreamWriter writer = null; if (!markdownFile.canWrite()) {
try { return false;
writer = new OutputStreamWriter( }
new FileOutputStream(markdownFile)
); OutputStreamWriter writer = null;
writer.write(this.content); try {
code = SUCCESS; writer = new OutputStreamWriter(
} catch (IOException e) { new FileOutputStream(markdownFile)
code = WRITE_ERROR; );
} writer.write(this.content);
} catch (IOException e) {
return false;
} finally {
if (writer != null) { if (writer != null) {
try { try {
writer.close(); writer.close();
@ -193,11 +170,10 @@ public class MarkdownFile {
// closing the reader failed // closing the reader failed
} }
} }
} else {
code = WRITE_ERROR;
} }
this.name = markdownFile.getName(); this.name = markdownFile.getName();
this.path = markdownFile.getParentFile().getAbsolutePath(); this.path = markdownFile.getParentFile().getAbsolutePath();
return code; return true;
} }
} }

View file

@ -16,7 +16,8 @@ public interface MarkdownPresenter {
void loadMarkdown(InputStream in); void loadMarkdown(InputStream in);
void loadMarkdown(File file); void loadMarkdown(File file);
void loadFromUri(Context context, Uri fileUri); void loadFromUri(Context context, Uri fileUri);
void loadTempMarkdown(InputStream in, OnTempFileLoadedListener listener);
void loadMarkdown(InputStream in, OnTempFileLoadedListener listener);
void newFile(String path); void newFile(String path);
void setEditView(MarkdownEditView editView); void setEditView(MarkdownEditView editView);
void setPreviewView(MarkdownPreviewView previewView); void setPreviewView(MarkdownPreviewView previewView);
@ -31,12 +32,13 @@ public interface MarkdownPresenter {
String getMarkdown(); String getMarkdown();
void setMarkdown(String markdown); void setMarkdown(String markdown);
abstract class OnTempFileLoadedListener { interface OnTempFileLoadedListener {
public abstract void onSuccess(String markdown); void onSuccess(String markdown);
public abstract void onError(int code);
void onError();
} }
interface MarkdownSavedListener { interface MarkdownSavedListener {
void saveComplete(); void saveComplete(boolean success);
} }
} }

View file

@ -5,25 +5,22 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.util.Log;
import com.commonsware.cwac.anddown.AndDown; import com.commonsware.cwac.anddown.AndDown;
import com.wbrawner.simplemarkdown.Utils;
import com.wbrawner.simplemarkdown.model.MarkdownFile; import com.wbrawner.simplemarkdown.model.MarkdownFile;
import com.wbrawner.simplemarkdown.view.MarkdownEditView; import com.wbrawner.simplemarkdown.view.MarkdownEditView;
import com.wbrawner.simplemarkdown.view.MarkdownPreviewView; import com.wbrawner.simplemarkdown.view.MarkdownPreviewView;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
public class MarkdownPresenterImpl implements MarkdownPresenter { public class MarkdownPresenterImpl implements MarkdownPresenter {
private MarkdownFile file; private MarkdownFile file;
private MarkdownEditView editView; private MarkdownEditView editView;
private MarkdownPreviewView previewView; private MarkdownPreviewView previewView;
private String TAG = MarkdownPresenterImpl.class.getSimpleName();
private int HOEDOWN_FLAGS =
AndDown.HOEDOWN_EXT_STRIKETHROUGH | AndDown.HOEDOWN_EXT_TABLES |
AndDown.HOEDOWN_EXT_UNDERLINE | AndDown.HOEDOWN_EXT_SUPERSCRIPT |
AndDown.HOEDOWN_EXT_FENCED_CODE;
private Handler fileHandler = new Handler(); private Handler fileHandler = new Handler();
public MarkdownPresenterImpl(MarkdownFile file) { public MarkdownPresenterImpl(MarkdownFile file) {
@ -44,14 +41,12 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
@Override @Override
public void loadMarkdown() { public void loadMarkdown() {
Runnable fileLoader = () -> { Runnable fileLoader = () -> {
int result = this.file.load(); boolean result = this.file.load();
if (editView != null) { if (editView != null) {
if (result == MarkdownFile.SUCCESS) { editView.onFileLoaded(result);
editView.setMarkdown(getMarkdown()); editView.setMarkdown(getMarkdown());
onMarkdownEdited(); onMarkdownEdited();
} else {
editView.showFileLoadeddError(result);
}
} }
}; };
fileHandler.post(fileLoader); fileHandler.post(fileLoader);
@ -59,47 +54,36 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
@Override @Override
public void loadMarkdown(File file) { public void loadMarkdown(File file) {
Runnable fileLoader = () -> { InputStream in = null;
int result = this.file.load(file); try {
if (editView != null) { in = new FileInputStream(file);
if (result == MarkdownFile.SUCCESS) { loadMarkdown(in);
editView.setTitle(this.file.getName()); } catch (FileNotFoundException e) {
editView.setMarkdown(getMarkdown()); System.err.println(e.getLocalizedMessage());
onMarkdownEdited(); e.printStackTrace();
} else { } finally {
editView.showFileLoadeddError(result); Utils.closeQuietly(in);
} }
}
};
fileHandler.post(fileLoader);
} }
@Override @Override
public void loadMarkdown(InputStream in) { public void loadMarkdown(InputStream in) {
Runnable fileLoader = () -> { this.loadMarkdown(in, null);
int result = file.load(in);
if (result == MarkdownFile.SUCCESS) {
if (editView != null)
editView.setMarkdown(getMarkdown());
onMarkdownEdited();
} else {
if (editView != null)
editView.showFileLoadeddError(result);
}
};
fileHandler.post(fileLoader);
} }
@Override @Override
public void loadTempMarkdown(InputStream in, OnTempFileLoadedListener listener) { public void loadMarkdown(final InputStream in, final OnTempFileLoadedListener listener) {
Runnable fileLoader = () -> { Runnable fileLoader = () -> {
MarkdownFile tmpFile = new MarkdownFile(); MarkdownFile tmpFile = new MarkdownFile();
int result = tmpFile.load(in); if (tmpFile.load(in)) {
if (result == MarkdownFile.SUCCESS) {
String html = generateHTML(tmpFile.getContent()); String html = generateHTML(tmpFile.getContent());
listener.onSuccess(html); if (listener != null) {
listener.onSuccess(html);
}
} else { } else {
listener.onError(result); if (listener != null) {
listener.onError();
}
} }
}; };
fileHandler.post(fileLoader); fileHandler.post(fileLoader);
@ -128,19 +112,12 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
@Override @Override
public void saveMarkdown(MarkdownSavedListener listener, String filePath) { public void saveMarkdown(MarkdownSavedListener listener, String filePath) {
Runnable fileSaver = () -> { Runnable fileSaver = () -> {
int code; boolean result = file.save(filePath);
code = file.save(filePath);
if (listener != null) { if (listener != null) {
listener.saveComplete(); listener.saveComplete(result);
} }
if (editView != null) { if (editView != null) {
if (code == MarkdownFile.SUCCESS) { editView.onFileSaved(result);
editView.showFileSavedMessage();
} else {
editView.showFileSavedError(code);
}
} }
}; };
fileHandler.post(fileSaver); fileHandler.post(fileSaver);
@ -164,6 +141,9 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
@Override @Override
public String generateHTML(String markdown) { public String generateHTML(String markdown) {
AndDown andDown = new AndDown(); AndDown andDown = new AndDown();
int HOEDOWN_FLAGS = AndDown.HOEDOWN_EXT_STRIKETHROUGH | AndDown.HOEDOWN_EXT_TABLES |
AndDown.HOEDOWN_EXT_UNDERLINE | AndDown.HOEDOWN_EXT_SUPERSCRIPT |
AndDown.HOEDOWN_EXT_FENCED_CODE;
return andDown.markdownToHtml(markdown, HOEDOWN_FLAGS, 0); return andDown.markdownToHtml(markdown, HOEDOWN_FLAGS, 0);
} }
@ -210,14 +190,16 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
.getColumnIndex(OpenableColumns.DISPLAY_NAME); .getColumnIndex(OpenableColumns.DISPLAY_NAME);
retCur.moveToFirst(); retCur.moveToFirst();
setFileName(retCur.getString(nameIndex)); setFileName(retCur.getString(nameIndex));
retCur.close();
} }
} else if (fileUri.getScheme().equals("file")) { } else if (fileUri.getScheme().equals("file")) {
setFileName(fileUri.getLastPathSegment()); setFileName(fileUri.getLastPathSegment());
} }
loadMarkdown(in); loadMarkdown(in);
} catch (Exception e) { } catch (Exception e) {
if (editView != null) if (editView != null) {
editView.showFileLoadeddError(MarkdownFile.READ_ERROR); editView.onFileLoaded(false);
}
} }
} }
} }

View file

@ -0,0 +1,36 @@
package com.wbrawner.simplemarkdown.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class DisableableViewPager extends ViewPager {
private boolean isSwipeLocked = false;
public DisableableViewPager(@NonNull Context context) {
super(context);
}
public DisableableViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return !isSwipeLocked && super.onInterceptTouchEvent(ev);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
return !isSwipeLocked && super.onTouchEvent(ev);
}
public void setSwipeLocked(boolean locked) {
this.isSwipeLocked = locked;
}
}

View file

@ -1,11 +1,13 @@
package com.wbrawner.simplemarkdown.view; package com.wbrawner.simplemarkdown.view;
import java.io.File;
public interface MarkdownEditView { public interface MarkdownEditView {
String getMarkdown(); String getMarkdown();
void setMarkdown(String markdown); void setMarkdown(String markdown);
void setTitle(String title); void setTitle(String title);
void showFileSavedMessage();
void showFileSavedError(int code); void onFileSaved(boolean success);
void showFileLoadedMessage();
void showFileLoadeddError(int code); void onFileLoaded(boolean success);
} }

View file

@ -3,12 +3,13 @@ package com.wbrawner.simplemarkdown.view.activity;
import android.Manifest; import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
@ -20,6 +21,7 @@ import com.wbrawner.simplemarkdown.MarkdownApplication;
import com.wbrawner.simplemarkdown.R; import com.wbrawner.simplemarkdown.R;
import com.wbrawner.simplemarkdown.Utils; import com.wbrawner.simplemarkdown.Utils;
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter; import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
import com.wbrawner.simplemarkdown.view.DisableableViewPager;
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter; import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter;
import java.io.File; import java.io.File;
@ -39,17 +41,15 @@ public class MainActivity extends AppCompatActivity
static final String EXTRA_FILE = "EXTRA_FILE"; static final String EXTRA_FILE = "EXTRA_FILE";
static final String EXTRA_FILE_PATH = "EXTRA_FILE_PATH"; static final String EXTRA_FILE_PATH = "EXTRA_FILE_PATH";
static final String EXTRA_REQUEST_CODE = "EXTRA_REQUEST_CODE"; static final String EXTRA_REQUEST_CODE = "EXTRA_REQUEST_CODE";
public static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider";
@Inject @Inject
MarkdownPresenter presenter; MarkdownPresenter presenter;
@BindView(R.id.pager) @BindView(R.id.pager)
ViewPager pager; DisableableViewPager pager;
@BindView(R.id.layout_tab) @BindView(R.id.layout_tab)
TabLayout tabLayout; TabLayout tabLayout;
private static final String TAG = MainActivity.class.getSimpleName();
private NewFileHandler newFileHandler; private NewFileHandler newFileHandler;
@Override @Override
@ -140,6 +140,10 @@ public class MainActivity extends AppCompatActivity
case R.id.action_new: case R.id.action_new:
presenter.saveMarkdown(newFileHandler, null); presenter.saveMarkdown(newFileHandler, null);
break; break;
case R.id.action_lock_swipe:
item.setChecked(!item.isChecked());
pager.setSwipeLocked(item.isChecked());
break;
case R.id.action_help: case R.id.action_help:
showInfoActivity(R.id.action_help); showInfoActivity(R.id.action_help);
break; break;
@ -171,8 +175,11 @@ public class MainActivity extends AppCompatActivity
infoIntent.putExtra("title", title); infoIntent.putExtra("title", title);
InputStream in = null; InputStream in = null;
try { try {
in = getAssets().open(fileName); AssetManager assetManager = getAssets();
presenter.loadTempMarkdown(in, new MarkdownPresenter.OnTempFileLoadedListener() { if (assetManager != null) {
in = assetManager.open(fileName);
}
presenter.loadMarkdown(in, new MarkdownPresenter.OnTempFileLoadedListener() {
@Override @Override
public void onSuccess(String html) { public void onSuccess(String html) {
infoIntent.putExtra("html", html); infoIntent.putExtra("html", html);
@ -180,7 +187,7 @@ public class MainActivity extends AppCompatActivity
} }
@Override @Override
public void onError(int code) { public void onError() {
Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT) Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT)
.show(); .show();
} }
@ -188,17 +195,14 @@ public class MainActivity extends AppCompatActivity
} catch (Exception e) { } catch (Exception e) {
Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT).show();
} }
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, public void onRequestPermissionsResult(
String permissions[], int[] grantResults) { int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults
) {
switch (requestCode) { switch (requestCode) {
case WRITE_PERMISSION_REQUEST: { case WRITE_PERMISSION_REQUEST: {
// If request is cancelled, the result arrays are empty. // If request is cancelled, the result arrays are empty.
@ -293,9 +297,17 @@ public class MainActivity extends AppCompatActivity
private class NewFileHandler implements MarkdownPresenter.MarkdownSavedListener { private class NewFileHandler implements MarkdownPresenter.MarkdownSavedListener {
@Override @Override
public void saveComplete() { public void saveComplete(boolean success) {
String newFile = Utils.getDefaultFileName(MainActivity.this); if (success) {
presenter.newFile(newFile); String newFile = Utils.getDefaultFileName(MainActivity.this);
presenter.newFile(newFile);
} else {
Toast.makeText(
MainActivity.this,
R.string.file_save_error,
Toast.LENGTH_SHORT
).show();
}
} }
} }
} }

View file

@ -1,15 +1,13 @@
package com.wbrawner.simplemarkdown.view.activity; package com.wbrawner.simplemarkdown.view.activity;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView; import android.webkit.WebView;
import com.wbrawner.simplemarkdown.R; import com.wbrawner.simplemarkdown.R;
import com.wbrawner.simplemarkdown.view.fragment.PreviewFragment;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -24,15 +22,19 @@ public class MarkdownInfoActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_markdown_info); setContentView(R.layout.activity_markdown_info);
ButterKnife.bind(this); ButterKnife.bind(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
Intent intent = getIntent(); Intent intent = getIntent();
if (intent == null || !intent.hasExtra("title") || !intent.hasExtra("html")) if (intent == null || !intent.hasExtra("title") || !intent.hasExtra("html")) {
finish(); finish();
return;
}
setTitle(intent.getStringExtra("title")); setTitle(intent.getStringExtra("title"));
String style = "<style>pre {overflow:scroll;}</style>";
infoWebview.loadDataWithBaseURL( infoWebview.loadDataWithBaseURL(
null, null,
style + intent.getStringExtra("html"), PreviewFragment.style + intent.getStringExtra("html"),
"text/html", "text/html",
"UTF-8", "UTF-8",
null null

View file

@ -1,7 +1,8 @@
package com.wbrawner.simplemarkdown.view.fragment; package com.wbrawner.simplemarkdown.view.fragment;
import android.app.AlertDialog; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -14,7 +15,6 @@ import com.jakewharton.rxbinding2.widget.RxTextView;
import com.wbrawner.simplemarkdown.MarkdownApplication; import com.wbrawner.simplemarkdown.MarkdownApplication;
import com.wbrawner.simplemarkdown.R; import com.wbrawner.simplemarkdown.R;
import com.wbrawner.simplemarkdown.Utils; import com.wbrawner.simplemarkdown.Utils;
import com.wbrawner.simplemarkdown.model.MarkdownFile;
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter; import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
import com.wbrawner.simplemarkdown.view.MarkdownEditView; import com.wbrawner.simplemarkdown.view.MarkdownEditView;
@ -30,40 +30,36 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
public class EditFragment extends Fragment implements MarkdownEditView { public class EditFragment extends Fragment implements MarkdownEditView {
public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE";
public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD";
private String TAG = EditFragment.class.getSimpleName();
private Unbinder unbinder;
@Inject @Inject
MarkdownPresenter presenter; MarkdownPresenter presenter;
@BindView(R.id.markdown_edit) @BindView(R.id.markdown_edit)
EditText markdownEditor; EditText markdownEditor;
private Unbinder unbinder;
public EditFragment() { public EditFragment() {
// Required empty public constructor // Required empty public constructor
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_edit, container, false); View view = inflater.inflate(R.layout.fragment_edit, container, false);
unbinder = ButterKnife.bind(this, view); unbinder = ButterKnife.bind(this, view);
((MarkdownApplication) getActivity().getApplication()).getComponent().inject(this); Activity activity = getActivity();
if (activity != null) {
((MarkdownApplication) activity.getApplication()).getComponent().inject(this);
}
Observable<String> obs = RxTextView.textChanges(markdownEditor) Observable<String> obs = RxTextView.textChanges(markdownEditor)
.debounce(50, TimeUnit.MILLISECONDS).map(CharSequence::toString); .debounce(50, TimeUnit.MILLISECONDS).map(CharSequence::toString);
obs.subscribeOn(Schedulers.io()); obs.subscribeOn(Schedulers.io());
obs.observeOn(AndroidSchedulers.mainThread()); obs.observeOn(AndroidSchedulers.mainThread());
obs.subscribe(markdown -> { obs.subscribe(markdown -> presenter.onMarkdownEdited(markdown));
presenter.onMarkdownEdited(markdown);
});
return view; return view;
} }
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
presenter.setEditView(EditFragment.this); presenter.setEditView(EditFragment.this);
presenter.loadMarkdown(); presenter.loadMarkdown();
@ -87,47 +83,37 @@ public class EditFragment extends Fragment implements MarkdownEditView {
return markdownEditor.getText().toString(); return markdownEditor.getText().toString();
} }
@Override
public void setMarkdown(String markdown) {
markdownEditor.setText(markdown);
}
@Override @Override
public void setTitle(String title) { public void setTitle(String title) {
getActivity().setTitle(title); Activity activity = getActivity();
if (activity != null) {
activity.setTitle(title);
}
} }
@Override @Override
public void showFileSavedMessage() { public void onFileSaved(boolean success) {
String location = Utils.getDocsPath(getActivity()) + presenter.getFileName(); String location = Utils.getDocsPath(getActivity()) + presenter.getFileName();
String message = getString(R.string.file_saved, location); String message;
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); if (success) {
} message = getString(R.string.file_saved, location);
} else {
@Override message = getString(R.string.file_save_error);
public void showFileSavedError(int code) {
String message = "";
switch (code) {
case MarkdownFile.WRITE_ERROR:
message = getString(R.string.error_write);
break;
default:
message = getString(R.string.file_save_error);
} }
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
} }
@Override @Override
public void showFileLoadedMessage() { public void onFileLoaded(boolean success) {
Toast.makeText(getActivity(), R.string.file_loaded, Toast.LENGTH_SHORT).show(); int message = success ? R.string.file_loaded : R.string.file_load_error;
}
@Override
public void showFileLoadeddError(int code) {
String message = "";
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
} }
@Override
public void setMarkdown(String markdown) {
markdownEditor.setText(markdown);
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();

View file

@ -1,6 +1,8 @@
package com.wbrawner.simplemarkdown.view.fragment; package com.wbrawner.simplemarkdown.view.fragment;
import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -22,32 +24,39 @@ import butterknife.Unbinder;
public class PreviewFragment extends Fragment implements MarkdownPreviewView { public class PreviewFragment extends Fragment implements MarkdownPreviewView {
private static final String TAG = PreviewFragment.class.getSimpleName(); private static final String TAG = PreviewFragment.class.getSimpleName();
private Unbinder unbinder; public static String style = "<style>" +
"pre {overflow:scroll; padding:15px; background: #F1F1F1;}" +
"</style>";
@Inject @Inject
MarkdownPresenter presenter; MarkdownPresenter presenter;
@BindView(R.id.markdown_view) @BindView(R.id.markdown_view)
WebView markdownPreview; WebView markdownPreview;
private Unbinder unbinder;
public PreviewFragment() { public PreviewFragment() {
// Required empty public constructor // Required empty public constructor
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(
Bundle savedInstanceState) { @NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_preview, container, false); View view = inflater.inflate(R.layout.fragment_preview, container, false);
unbinder = ButterKnife.bind(this, view); unbinder = ButterKnife.bind(this, view);
((MarkdownApplication) getActivity().getApplication()).getComponent().inject(this); Activity activity = getActivity();
if (activity != null) {
((MarkdownApplication) activity.getApplication()).getComponent().inject(this);
}
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
WebView.setWebContentsDebuggingEnabled(true); WebView.setWebContentsDebuggingEnabled(true);
return view; return view;
} }
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
} }
@ -56,9 +65,13 @@ public class PreviewFragment extends Fragment implements MarkdownPreviewView {
@Override @Override
public void updatePreview(String html) { public void updatePreview(String html) {
if (markdownPreview != null) { if (markdownPreview != null) {
markdownPreview.post(() -> { markdownPreview.post(() -> markdownPreview.loadDataWithBaseURL(
markdownPreview.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null); null,
}); style + html,
"text/html",
"UTF-8",
null
));
} }
} }

View file

@ -3,26 +3,27 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v4.view.ViewPager
<com.wbrawner.simplemarkdown.view.DisableableViewPager
android:id="@+id/pager" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.TabLayout <android.support.design.widget.TabLayout
android:id="@+id/layout_tab"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/layout_tab"
android:layout_gravity="top"> android:layout_gravity="top">
<android.support.design.widget.TabItem <android.support.design.widget.TabItem
android:id="@+id/tab_edit"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/action_edit" android:text="@string/action_edit" />
android:id="@+id/tab_edit" />
<android.support.design.widget.TabItem <android.support.design.widget.TabItem
android:id="@+id/tab_preview"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/action_preview" android:text="@string/action_preview" />
android:id="@+id/tab_preview" />
</android.support.design.widget.TabLayout> </android.support.design.widget.TabLayout>
</android.support.v4.view.ViewPager> </com.wbrawner.simplemarkdown.view.DisableableViewPager>
</LinearLayout> </LinearLayout>

View file

@ -2,38 +2,38 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:title="@string/action_share"
android:id="@+id/action_share" android:id="@+id/action_share"
android:icon="@drawable/ic_action_share" android:icon="@drawable/ic_action_share"
android:title="@string/action_share"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item <item
android:title="@string/action_save"
android:id="@+id/action_save" android:id="@+id/action_save"
android:icon="@drawable/ic_action_save" android:icon="@drawable/ic_action_save"
android:title="@string/action_save"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/action_load" android:id="@+id/action_load"
android:orderInCategory="100"
android:title="@string/action_open" android:title="@string/action_open"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/action_new" android:id="@+id/action_new"
android:orderInCategory="150"
android:title="@string/action_new" android:title="@string/action_new"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_lock_swipe"
android:checkable="true"
android:title="@string/action_lock_swipe"
app:showAsAction="never" />
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"
android:orderInCategory="200"
android:title="@string/action_settings" android:title="@string/action_settings"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/action_help" android:id="@+id/action_help"
android:orderInCategory="200"
android:title="@string/action_help" android:title="@string/action_help"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/action_libraries" android:id="@+id/action_libraries"
android:orderInCategory="300"
android:title="@string/action_libraries" android:title="@string/action_libraries"
app:showAsAction="never" /> app:showAsAction="never" />
</menu> </menu>

View file

@ -32,4 +32,5 @@
<string name="title_activity_settings">Settings</string> <string name="title_activity_settings">Settings</string>
<string name="pref_title_autosave">Enable autosave</string> <string name="pref_title_autosave">Enable autosave</string>
<string name="pref_description_autosave">Automatically save files when closing the app</string> <string name="pref_description_autosave">Automatically save files when closing the app</string>
<string name="action_lock_swipe">Lock Swiping</string>
</resources> </resources>