Began implementing RxJava
This commit is contained in:
parent
f5a7333e84
commit
e4ba6d39bc
5 changed files with 150 additions and 392 deletions
|
@ -1,5 +1,7 @@
|
||||||
package com.wbrawner.simplemarkdown;
|
package com.wbrawner.simplemarkdown;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.ViewModelProvider;
|
||||||
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -44,159 +46,29 @@ import static android.content.ContentValues.TAG;
|
||||||
public class EditFragment extends Fragment {
|
public class EditFragment extends Fragment {
|
||||||
public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE";
|
public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE";
|
||||||
public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD";
|
public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD";
|
||||||
private static EditText mMarkdownEditor;
|
private MarkdownViewModel markdownViewModel;
|
||||||
private FileUtils mFileUtils;
|
|
||||||
|
|
||||||
@BindView(R.id.markdown_edit)
|
@BindView(R.id.markdown_edit)
|
||||||
EditText markdownEditor;
|
EditText markdownEditor;
|
||||||
|
|
||||||
private FragmentActivity mContext;
|
|
||||||
|
|
||||||
private File mTmpFile;
|
|
||||||
private boolean loadTmpFile = true;
|
|
||||||
|
|
||||||
public EditFragment() {
|
public EditFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction(SAVE_ACTION);
|
|
||||||
filter.addAction(LOAD_ACTION);
|
|
||||||
LocalBroadcastManager.getInstance(getContext()).registerReceiver(
|
|
||||||
new EditFragment.MarkdownBroadcastSaveReceiver(),
|
|
||||||
filter
|
|
||||||
);
|
|
||||||
mContext = getActivity();
|
|
||||||
mFileUtils = new FileUtils(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(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);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
mMarkdownEditor = markdownEditor;
|
markdownViewModel = ViewModelProviders.of(getActivity()).get(MarkdownViewModel.class);
|
||||||
if (mMarkdownEditor.requestFocus()) {
|
Observable<String> obs = RxTextView.textChanges(markdownEditor)
|
||||||
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
Observable<String> obs = RxTextView.textChanges(mMarkdownEditor)
|
|
||||||
.debounce(50, TimeUnit.MILLISECONDS).map(editable -> editable.toString());
|
.debounce(50, TimeUnit.MILLISECONDS).map(editable -> editable.toString());
|
||||||
obs.subscribeOn(Schedulers.io());
|
obs.subscribeOn(Schedulers.io());
|
||||||
obs.observeOn(AndroidSchedulers.mainThread());
|
obs.observeOn(AndroidSchedulers.mainThread());
|
||||||
obs.subscribe(string -> {
|
obs.subscribe(data -> {
|
||||||
Log.d(TAG, "debounced " + string);
|
markdownViewModel.updateMarkdown(data);
|
||||||
updatePreview(mContext);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
if (getActivity().getIntent().getAction().equals(Intent.ACTION_MAIN)) {
|
|
||||||
File tmpFile = new File(getActivity().getFilesDir() + "/" + MainActivity.getTempFileName());
|
|
||||||
if (tmpFile.exists()) {
|
|
||||||
FileLoadTask loadTask = new FileLoadTask(mContext, EditFragment.this);
|
|
||||||
loadTask.execute(FileProvider.getUriForFile(mContext, MainActivity.AUTHORITY, tmpFile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updatePreview(Context context) {
|
|
||||||
Intent broadcastIntent = new Intent(PreviewFragment.PREVIEW_ACTION);
|
|
||||||
broadcastIntent.putExtra("markdownData", mMarkdownEditor.getText().toString());
|
|
||||||
Layout layout = mMarkdownEditor.getLayout();
|
|
||||||
if (layout != null) {
|
|
||||||
int line =
|
|
||||||
layout.getLineForOffset(mMarkdownEditor.getSelectionStart());
|
|
||||||
int baseline = layout.getLineBaseline(line);
|
|
||||||
int ascent = layout.getLineAscent(line);
|
|
||||||
float yPos = (baseline + ascent) * 1.0f;
|
|
||||||
float yPercent = yPos / mMarkdownEditor.getMeasuredHeight();
|
|
||||||
broadcastIntent.putExtra("scrollY", yPercent);
|
|
||||||
}
|
|
||||||
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(context);
|
|
||||||
manager.sendBroadcast(broadcastIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(String data, String filePath) {
|
|
||||||
// TODO: move this to AsyncTask
|
|
||||||
if (!mFileUtils.isExternalStorageWriteable()) {
|
|
||||||
mFileUtils.requestWritePermissions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (filePath == null) {
|
|
||||||
filePath = MainActivity.getFilePath() + MainActivity.getFileName();
|
|
||||||
}
|
|
||||||
FileOutputStream out = null;
|
|
||||||
try {
|
|
||||||
Log.d(TAG, "File path: " + filePath);
|
|
||||||
File tmpFile = new File(filePath);
|
|
||||||
out = new FileOutputStream(tmpFile);
|
|
||||||
out.write(data.getBytes());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error saving temp file:", e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (out != null) {
|
|
||||||
out.close();
|
|
||||||
Toast.makeText(mContext, getString(R.string.file_saved, filePath), Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Error closing write stream", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(String data) {
|
|
||||||
save(data, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save() {
|
|
||||||
save(mMarkdownEditor.getText().toString(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
save(mMarkdownEditor.getText().toString(),
|
|
||||||
MainActivity.getTempFilePath() + MainActivity.getFileName());
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEditorText(String s) {
|
|
||||||
mMarkdownEditor.setText(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MarkdownBroadcastSaveReceiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
Log.d(TAG, "Intent received: " + intent.getAction());
|
|
||||||
switch (intent.getAction()) {
|
|
||||||
case SAVE_ACTION:
|
|
||||||
if (intent.hasExtra("fileName")) {
|
|
||||||
String fileName = intent.getStringExtra("fileName");
|
|
||||||
if (!fileName.contains("/")) {
|
|
||||||
fileName = MainActivity.getFilePath() + "/" + fileName;
|
|
||||||
}
|
|
||||||
if (!fileName.endsWith(".md"))
|
|
||||||
fileName += ".md";
|
|
||||||
save(mMarkdownEditor.getText().toString(), fileName);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LOAD_ACTION:
|
|
||||||
if (intent.hasExtra("fileUri")) {
|
|
||||||
FileLoadTask loadTask = new FileLoadTask(mContext, EditFragment.this);
|
|
||||||
loadTask.execute(Uri.parse(intent.getStringExtra("fileUri")));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import static android.content.ContentValues.TAG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by billy on 7/25/17.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class FileLoadTask extends AsyncTask<Uri, String, String> {
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private EditFragment mEditFragment;
|
|
||||||
|
|
||||||
public FileLoadTask(Context context, EditFragment editFragment) {
|
|
||||||
mContext = context;
|
|
||||||
mEditFragment = editFragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(Uri... uris) {
|
|
||||||
if (mContext == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BufferedReader reader = null;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
FileOutputStream out = null;
|
|
||||||
try {
|
|
||||||
InputStream in = mContext.getContentResolver().openInputStream(uris[0]);
|
|
||||||
File tmpFile = new File(mContext.getFilesDir() + "/" + MainActivity.getTempFileName());
|
|
||||||
if (tmpFile.exists())
|
|
||||||
tmpFile.delete();
|
|
||||||
out = new FileOutputStream(tmpFile);
|
|
||||||
reader = new BufferedReader(new InputStreamReader(in));
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
sb.append(line);
|
|
||||||
sb.append("\r\n");
|
|
||||||
out.write(line.getBytes());
|
|
||||||
out.write("\r\n".getBytes());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error opening file:", e);
|
|
||||||
} finally {
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (out != null) {
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (Exception e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(String s) {
|
|
||||||
super.onPostExecute(s);
|
|
||||||
mEditFragment.setEditorText(s);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -60,32 +60,6 @@ public class MainActivity extends AppCompatActivity
|
||||||
TabLayout tabLayout;
|
TabLayout tabLayout;
|
||||||
|
|
||||||
private static final String TAG = MainActivity.class.getSimpleName();
|
private static final String TAG = MainActivity.class.getSimpleName();
|
||||||
private static String fileName;
|
|
||||||
|
|
||||||
public static String getTempFileName() {
|
|
||||||
return "tmp_" + getFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFileName() {
|
|
||||||
if (fileName == null) {
|
|
||||||
return "untitled.md";
|
|
||||||
}
|
|
||||||
if (!fileName.endsWith(".md"))
|
|
||||||
return fileName + ".md";
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getTempFilePath() {
|
|
||||||
return mFilesDir + "/tmp/";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFilePath() {
|
|
||||||
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setFileName(String fileName) {
|
|
||||||
MainActivity.fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -127,79 +101,79 @@ public class MainActivity extends AppCompatActivity
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
// public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
// switch (item.getItemId()) {
|
||||||
case R.id.action_save:
|
// case R.id.action_save:
|
||||||
//TODO: Create popup for file name
|
// //TODO: Create popup for file name
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
// AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(R.string.action_save);
|
// builder.setTitle(R.string.action_save);
|
||||||
|
//
|
||||||
final EditText input = new EditText(this);
|
// final EditText input = new EditText(this);
|
||||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
// input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
input.setHint(R.string.hint_filename);
|
// input.setHint(R.string.hint_filename);
|
||||||
input.setText(getFileName());
|
// input.setText(getFileName());
|
||||||
builder.setView(input);
|
// builder.setView(input);
|
||||||
|
//
|
||||||
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
// builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
// public void onClick(DialogInterface dialog, int which) {
|
||||||
if (input.getText().length() > 0) {
|
// if (input.getText().length() > 0) {
|
||||||
setFileName(input.getText().toString());
|
// setFileName(input.getText().toString());
|
||||||
requestSave(input.getText().toString());
|
// requestSave(input.getText().toString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
// builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
// public void onClick(DialogInterface dialog, int which) {
|
||||||
dialog.cancel();
|
// dialog.cancel();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
builder.show();
|
// builder.show();
|
||||||
break;
|
// break;
|
||||||
case R.id.action_share:
|
// case R.id.action_share:
|
||||||
//TODO: Fix this
|
// //TODO: Fix this
|
||||||
File tmpFile = new File(getTempFilePath() + getFileName());
|
// File tmpFile = new File(getTempFilePath() + getFileName());
|
||||||
if (!tmpFile.exists()) {
|
// if (!tmpFile.exists()) {
|
||||||
Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
|
// Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
|
||||||
saveIntent.putExtra("fileName", getTempFilePath() + getFileName());
|
// saveIntent.putExtra("fileName", getTempFilePath() + getFileName());
|
||||||
LocalBroadcastManager.getInstance(getApplicationContext())
|
// LocalBroadcastManager.getInstance(getApplicationContext())
|
||||||
.sendBroadcast(saveIntent);
|
// .sendBroadcast(saveIntent);
|
||||||
}
|
// }
|
||||||
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile);
|
// Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile);
|
||||||
if (fileUri != null) {
|
// if (fileUri != null) {
|
||||||
try {
|
// try {
|
||||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
// Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||||
shareIntent.setDataAndType(
|
// shareIntent.setDataAndType(
|
||||||
fileUri,
|
// fileUri,
|
||||||
getContentResolver().getType(fileUri)
|
// getContentResolver().getType(fileUri)
|
||||||
);
|
// );
|
||||||
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
// shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
||||||
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
// shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
startActivity(
|
// startActivity(
|
||||||
Intent.createChooser(
|
// Intent.createChooser(
|
||||||
shareIntent,
|
// shareIntent,
|
||||||
getString(R.string.share_file)
|
// getString(R.string.share_file)
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
} catch (ActivityNotFoundException e) {
|
// } catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG, "Error sharing file", e);
|
// Log.e(TAG, "Error sharing file", e);
|
||||||
Toast.makeText(
|
// Toast.makeText(
|
||||||
MainActivity.this,
|
// MainActivity.this,
|
||||||
R.string.no_shareable_apps,
|
// R.string.no_shareable_apps,
|
||||||
Toast.LENGTH_SHORT
|
// Toast.LENGTH_SHORT
|
||||||
).show();
|
// ).show();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case R.id.action_load:
|
// case R.id.action_load:
|
||||||
requestOpen();
|
// requestOpen();
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
return super.onOptionsItemSelected(item);
|
// return super.onOptionsItemSelected(item);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void requestSave(String text) {
|
private void requestSave(String text) {
|
||||||
Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
|
Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
|
||||||
|
@ -226,25 +200,25 @@ public class MainActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
// public void onRequestPermissionsResult(int requestCode,
|
||||||
String permissions[], int[] grantResults) {
|
// String permissions[], int[] grantResults) {
|
||||||
switch (requestCode) {
|
// switch (requestCode) {
|
||||||
case FileUtils.WRITE_PERMISSION_REQUEST: {
|
// case FileUtils.WRITE_PERMISSION_REQUEST: {
|
||||||
// If request is cancelled, the result arrays are empty.
|
// // If request is cancelled, the result arrays are empty.
|
||||||
if (grantResults.length > 0
|
// if (grantResults.length > 0
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
// && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
// Permission granted, open file chooser dialog
|
// // Permission granted, open file chooser dialog
|
||||||
requestSave(getFileName());
|
// requestSave(getFileName());
|
||||||
} else {
|
// } else {
|
||||||
// Permission denied, do nothing
|
// // Permission denied, do nothing
|
||||||
Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT)
|
// Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT)
|
||||||
.show();
|
// .show();
|
||||||
}
|
// }
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (pager.getCurrentItem() == FRAGMENT_EDIT)
|
if (pager.getCurrentItem() == FRAGMENT_EDIT)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.wbrawner.simplemarkdown;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
|
import android.arch.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.commonsware.cwac.anddown.AndDown;
|
||||||
|
|
||||||
|
public class MarkdownViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private MutableLiveData<String> markdownLiveData;
|
||||||
|
private MutableLiveData<String> htmlLiveData = new MutableLiveData<>();;
|
||||||
|
|
||||||
|
public MarkdownViewModel() {
|
||||||
|
markdownLiveData = new MutableLiveData<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMarkdown(String data) {
|
||||||
|
if (markdownLiveData == null)
|
||||||
|
markdownLiveData = new MutableLiveData<>();
|
||||||
|
markdownLiveData.postValue(data);
|
||||||
|
Runnable generateMarkdown = () -> {
|
||||||
|
AndDown andDown = new AndDown();
|
||||||
|
int hoedownFlags =
|
||||||
|
AndDown.HOEDOWN_EXT_STRIKETHROUGH | AndDown.HOEDOWN_EXT_TABLES |
|
||||||
|
AndDown.HOEDOWN_EXT_UNDERLINE | AndDown.HOEDOWN_EXT_SUPERSCRIPT |
|
||||||
|
AndDown.HOEDOWN_EXT_FENCED_CODE;
|
||||||
|
htmlLiveData.postValue(andDown.markdownToHtml(markdownLiveData.getValue(), hoedownFlags, 0));
|
||||||
|
};
|
||||||
|
if (markdownLiveData.getValue() != null)
|
||||||
|
generateMarkdown.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getHtml() {
|
||||||
|
return htmlLiveData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
package com.wbrawner.simplemarkdown;
|
package com.wbrawner.simplemarkdown;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.arch.lifecycle.LifecycleFragment;
|
||||||
|
import android.arch.lifecycle.Observer;
|
||||||
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -22,13 +25,20 @@ import android.webkit.WebView;
|
||||||
|
|
||||||
import com.commonsware.cwac.anddown.AndDown;
|
import com.commonsware.cwac.anddown.AndDown;
|
||||||
|
|
||||||
|
import org.reactivestreams.Subscriber;
|
||||||
|
import org.reactivestreams.Subscription;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.processors.PublishProcessor;
|
||||||
|
import io.reactivex.subjects.PublishSubject;
|
||||||
|
import io.reactivex.subjects.Subject;
|
||||||
|
|
||||||
public class PreviewFragment extends Fragment {
|
public class PreviewFragment extends LifecycleFragment {
|
||||||
private static final String TAG = PreviewFragment.class.getSimpleName();
|
private static final String TAG = PreviewFragment.class.getSimpleName();
|
||||||
private static final int INTERNET_REQUEST = 0;
|
private static final int INTERNET_REQUEST = 0;
|
||||||
private WebView mMarkdownView;
|
private MarkdownViewModel markdownViewModel;
|
||||||
|
|
||||||
@BindView(R.id.markdown_view)
|
@BindView(R.id.markdown_view)
|
||||||
WebView markdownView;
|
WebView markdownView;
|
||||||
|
@ -40,76 +50,17 @@ public class PreviewFragment extends Fragment {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction(PREVIEW_ACTION);
|
|
||||||
LocalBroadcastManager.getInstance(getContext()).registerReceiver(
|
|
||||||
new MarkdownBroadcastSender(),
|
|
||||||
filter
|
|
||||||
);
|
|
||||||
checkPermissions();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkPermissions() {
|
|
||||||
if (ContextCompat.checkSelfPermission(getActivity(),
|
|
||||||
Manifest.permission.INTERNET)
|
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
|
||||||
ActivityCompat.requestPermissions(getActivity(),
|
|
||||||
new String[]{Manifest.permission.INTERNET},
|
|
||||||
INTERNET_REQUEST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(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_preview, container, false);
|
View view = inflater.inflate(R.layout.fragment_preview, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
mMarkdownView = markdownView;
|
markdownViewModel = ViewModelProviders.of(getActivity()).get(MarkdownViewModel.class);
|
||||||
|
markdownViewModel.getHtml().observe(this, s -> markdownView.loadData(s, "text/html", "UTF-8"));
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
WebView.setWebContentsDebuggingEnabled(true);
|
WebView.setWebContentsDebuggingEnabled(true);
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MarkdownBroadcastSender extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
Log.d(TAG, "Intent received: " + intent.getAction());
|
|
||||||
switch (intent.getAction()) {
|
|
||||||
case PREVIEW_ACTION:
|
|
||||||
if (intent.hasExtra("markdownData")) {
|
|
||||||
String data = intent.getStringExtra("markdownData");
|
|
||||||
int yPos = 0;
|
|
||||||
if (intent.hasExtra("scrollY")) {
|
|
||||||
float yPercent = intent.getFloatExtra("scrollY", 0);
|
|
||||||
Log.d(TAG, "Scrolling to: " + yPercent);
|
|
||||||
yPos = Math.round(mMarkdownView.getContentHeight() * yPercent);
|
|
||||||
}
|
|
||||||
markdown(data, yPos);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markdown(final String text, final int scrollY) {
|
|
||||||
Thread setMarkdown = new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
AndDown andDown = new AndDown();
|
|
||||||
int hoedownFlags =
|
|
||||||
AndDown.HOEDOWN_EXT_STRIKETHROUGH | AndDown.HOEDOWN_EXT_TABLES |
|
|
||||||
AndDown.HOEDOWN_EXT_UNDERLINE | AndDown.HOEDOWN_EXT_SUPERSCRIPT |
|
|
||||||
AndDown.HOEDOWN_EXT_FENCED_CODE;
|
|
||||||
String html = andDown.markdownToHtml(text, hoedownFlags, 0);
|
|
||||||
mMarkdownView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
|
|
||||||
mMarkdownView.scrollTo(0, scrollY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
setMarkdown.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue