diff --git a/app/build.gradle b/app/build.gradle
index 39b5cbb..17c68d6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,6 +2,9 @@ apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
android {
+ configurations.all {
+ resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
+ }
packagingOptions {
exclude 'META-INF/LICENSE-LGPL-2.1.txt'
exclude 'META-INF/LICENSE-LGPL-3.txt'
@@ -49,9 +52,8 @@ dependencies {
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
- compile "android.arch.lifecycle:runtime:1.0.0-alpha5"
- compile "android.arch.lifecycle:extensions:1.0.0-alpha5"
+ compile 'com.google.dagger:dagger:2.11'
+ annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
testCompile 'junit:junit:4.12'
- annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha5"
annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c5f17bd..f3d5d59 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,13 +5,14 @@
-
+
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/AppComponent.java b/app/src/main/java/com/wbrawner/simplemarkdown/AppComponent.java
new file mode 100644
index 0000000..78d66f0
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/AppComponent.java
@@ -0,0 +1,22 @@
+package com.wbrawner.simplemarkdown;
+
+import com.wbrawner.simplemarkdown.view.activity.MainActivity;
+import com.wbrawner.simplemarkdown.view.fragment.EditFragment;
+import com.wbrawner.simplemarkdown.view.fragment.PreviewFragment;
+
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+@Singleton
+@Component(modules = { AppModule.class })
+public interface AppComponent {
+ void inject(MarkdownApplication application);
+ void inject(MainActivity activity);
+ void inject(EditFragment fragment);
+ void inject(PreviewFragment fragment);
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/AppModule.java b/app/src/main/java/com/wbrawner/simplemarkdown/AppModule.java
new file mode 100644
index 0000000..20fe822
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/AppModule.java
@@ -0,0 +1,27 @@
+package com.wbrawner.simplemarkdown;
+
+import com.wbrawner.simplemarkdown.model.MarkdownFile;
+import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
+import com.wbrawner.simplemarkdown.presentation.MarkdownPresenterImpl;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+@Module
+public class AppModule {
+ @Provides
+ public MarkdownFile provideMarkdownFile() {
+ return new MarkdownFile();
+ }
+
+ @Provides @Singleton
+ public MarkdownPresenter provideMarkdownPresenter(MarkdownFile file) {
+ return new MarkdownPresenterImpl(file);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java
deleted file mode 100644
index 26eb1d1..0000000
--- a/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.wbrawner.simplemarkdown;
-
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.content.FileProvider;
-import android.support.v4.content.LocalBroadcastManager;
-import android.text.Editable;
-import android.text.Layout;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import com.jakewharton.rxbinding2.widget.RxTextView;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import io.reactivex.Observable;
-import io.reactivex.Scheduler;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.schedulers.Schedulers;
-
-import static android.content.ContentValues.TAG;
-
-
-public class EditFragment extends Fragment {
- public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE";
- public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD";
- private MarkdownViewModel markdownViewModel;
-
- @BindView(R.id.markdown_edit)
- EditText markdownEditor;
-
- public EditFragment() {
- // Required empty public constructor
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- View view = inflater.inflate(R.layout.fragment_edit, container, false);
- ButterKnife.bind(this, view);
- markdownViewModel = ViewModelProviders.of(getActivity()).get(MarkdownViewModel.class);
- Observable obs = RxTextView.textChanges(markdownEditor)
- .debounce(50, TimeUnit.MILLISECONDS).map(editable -> editable.toString());
- obs.subscribeOn(Schedulers.io());
- obs.observeOn(AndroidSchedulers.mainThread());
- obs.subscribe(data -> {
- markdownViewModel.updateMarkdown(data);
- });
- return view;
- }
-}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java b/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java
deleted file mode 100644
index 1e35052..0000000
--- a/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.wbrawner.simplemarkdown;
-
-import android.Manifest;
-import android.app.Activity;
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.app.AppCompatActivity;
-
-/**
- * Created by billy on 7/27/2017.
- */
-
-public class FileUtils {
-
- public static final int WRITE_PERMISSION_REQUEST = 0;
- public static final int OPEN_FILE_REQUEST = 1;
-
- private Activity mContext;
-
- public FileUtils(Activity context) {
- mContext = context;
- }
-
- public boolean isExternalStorageWritable() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- return true;
- }
- return false;
- }
-
- public boolean isExternalStorageReadable() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state) ||
- Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- return true;
- }
- return false;
- }
-
- public boolean isExternalStorageWriteable() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state) && checkWritePermission()) {
- return true;
- }
- return false;
- }
-
- public boolean checkWritePermission() {
- return (ContextCompat.checkSelfPermission(
- mContext,
- Manifest.permission.WRITE_EXTERNAL_STORAGE
- ) == PackageManager.PERMISSION_GRANTED);
- }
-
- public void requestWritePermissions() {
- ActivityCompat.requestPermissions(
- mContext,
- new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
- WRITE_PERMISSION_REQUEST
- );
- }
-}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java
deleted file mode 100644
index 52834dc..0000000
--- a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java
+++ /dev/null
@@ -1,243 +0,0 @@
-package com.wbrawner.simplemarkdown;
-
-import android.Manifest;
-import android.app.ProgressDialog;
-import android.content.ActivityNotFoundException;
-import android.content.ClipData;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.Environment;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.FileProvider;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v4.os.EnvironmentCompat;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.InputType;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.SearchEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.MimeTypeMap;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import java.io.File;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-
-public class MainActivity extends AppCompatActivity
- implements ActivityCompat.OnRequestPermissionsResultCallback {
-
- public static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider";
- private static final int REQUEST_WRITE_STORAGE = 0;
- private static File mFilesDir;
- public static final int FRAGMENT_EDIT = 0;
- public static final int FRAGMENT_PREVIEW = 1;
- public static final int NUM_PAGES = 2;
-
- @BindView(R.id.pager)
- ViewPager pager;
- @BindView(R.id.layout_tab)
- TabLayout tabLayout;
-
- private static final String TAG = MainActivity.class.getSimpleName();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- getWindow().setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
- ButterKnife.bind(this);
- pager.setAdapter(
- new EditPagerAdapter(getSupportFragmentManager(), MainActivity.this)
- );
- pager.setPageMargin(1);
- pager.setPageMarginDrawable(R.color.colorAccent);
- mFilesDir = getFilesDir();
- Intent intent = getIntent();
- if (intent != null && !intent.getAction().equals(Intent.ACTION_MAIN) && intent.getData() != null) {
- Intent loadIntent = new Intent(EditFragment.LOAD_ACTION);
- loadIntent.putExtra("fileUri", intent.getData().toString());
- LocalBroadcastManager.getInstance(getApplicationContext())
- .sendBroadcast(loadIntent);
- }
- if (getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE) {
- tabLayout.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
- tabLayout.setVisibility(View.GONE);
- else
- tabLayout.setVisibility(View.VISIBLE);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_edit, menu);
- return true;
- }
-
-// @Override
-// public boolean onOptionsItemSelected(MenuItem item) {
-// switch (item.getItemId()) {
-// case R.id.action_save:
-// //TODO: Create popup for file name
-// AlertDialog.Builder builder = new AlertDialog.Builder(this);
-// builder.setTitle(R.string.action_save);
-//
-// final EditText input = new EditText(this);
-// input.setInputType(InputType.TYPE_CLASS_TEXT);
-// input.setHint(R.string.hint_filename);
-// input.setText(getFileName());
-// builder.setView(input);
-//
-// builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
-// @Override
-// public void onClick(DialogInterface dialog, int which) {
-// if (input.getText().length() > 0) {
-// setFileName(input.getText().toString());
-// requestSave(input.getText().toString());
-// }
-// }
-// });
-// builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
-// @Override
-// public void onClick(DialogInterface dialog, int which) {
-// dialog.cancel();
-// }
-// });
-//
-// builder.show();
-// break;
-// case R.id.action_share:
-// //TODO: Fix this
-// File tmpFile = new File(getTempFilePath() + getFileName());
-// if (!tmpFile.exists()) {
-// Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
-// saveIntent.putExtra("fileName", getTempFilePath() + getFileName());
-// LocalBroadcastManager.getInstance(getApplicationContext())
-// .sendBroadcast(saveIntent);
-// }
-// Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile);
-// if (fileUri != null) {
-// try {
-// Intent shareIntent = new Intent(Intent.ACTION_SEND);
-// shareIntent.setDataAndType(
-// fileUri,
-// getContentResolver().getType(fileUri)
-// );
-// shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
-// shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-// startActivity(
-// Intent.createChooser(
-// shareIntent,
-// getString(R.string.share_file)
-// )
-// );
-// } catch (ActivityNotFoundException e) {
-// Log.e(TAG, "Error sharing file", e);
-// Toast.makeText(
-// MainActivity.this,
-// R.string.no_shareable_apps,
-// Toast.LENGTH_SHORT
-// ).show();
-// }
-// }
-// break;
-// case R.id.action_load:
-// requestOpen();
-// break;
-// }
-// return super.onOptionsItemSelected(item);
-// }
-
- private void requestSave(String text) {
- Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
- saveIntent.putExtra("fileName", text);
- LocalBroadcastManager.getInstance(getApplicationContext())
- .sendBroadcast(saveIntent);
- }
-
- private void requestOpen() {
- Intent openIntent = new Intent(Intent.ACTION_GET_CONTENT);
- openIntent.setType("*/*");
- openIntent.addCategory(Intent.CATEGORY_OPENABLE);
- try {
- startActivityForResult(
- Intent.createChooser(
- openIntent,
- getString(R.string.open_file)
- ),
- FileUtils.OPEN_FILE_REQUEST
- );
- } catch (ActivityNotFoundException e) {
- Toast.makeText(MainActivity.this, R.string.no_filebrowser, Toast.LENGTH_SHORT)
- .show();
- }
- }
-
-// @Override
-// public void onRequestPermissionsResult(int requestCode,
-// String permissions[], int[] grantResults) {
-// switch (requestCode) {
-// case FileUtils.WRITE_PERMISSION_REQUEST: {
-// // If request is cancelled, the result arrays are empty.
-// if (grantResults.length > 0
-// && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-// // Permission granted, open file chooser dialog
-// requestSave(getFileName());
-// } else {
-// // Permission denied, do nothing
-// Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT)
-// .show();
-// }
-// return;
-// }
-// }
-// }
- @Override
- public void onBackPressed() {
- if (pager.getCurrentItem() == FRAGMENT_EDIT)
- super.onBackPressed();
- else
- pager.setCurrentItem(FRAGMENT_EDIT);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case FileUtils.OPEN_FILE_REQUEST:
- if (resultCode == RESULT_OK) {
- Uri fileUri = data.getData();
- Intent loadIntent = new Intent(EditFragment.LOAD_ACTION);
- loadIntent.putExtra("fileUri", fileUri.toString());
- LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(loadIntent);
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.java b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.java
new file mode 100644
index 0000000..93bbb9e
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.java
@@ -0,0 +1,24 @@
+package com.wbrawner.simplemarkdown;
+
+import android.app.Application;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public class MarkdownApplication extends Application {
+
+ private AppComponent component;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ component = DaggerAppComponent.builder()
+ .appModule(new AppModule())
+ .build();
+ }
+
+ public AppComponent getComponent() {
+ return component;
+ }
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.java b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.java
index 5129173..3cf17fa 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.java
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownViewModel.java
@@ -1,14 +1,10 @@
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 markdownLiveData;
+public class MarkdownViewModel {
+/*
+ private static final String TAG = MarkdownViewModel.class.getSimpleName();
+ private File file;
+ public MutableLiveData markdownLiveData;
private MutableLiveData htmlLiveData = new MutableLiveData<>();;
public MarkdownViewModel() {
@@ -34,4 +30,47 @@ public class MarkdownViewModel extends ViewModel {
public LiveData getHtml() {
return htmlLiveData;
}
+
+ public void openFile(String filePath) {
+ file = new File(filePath);
+ }
+
+ public String getFileName() {
+ if (file == null || file.getName().isEmpty())
+ return "Untitled.md";
+ return file.getName();
+ }
+
+ public boolean saveFile(String filePath, @Nullable String fileName) {
+ if (fileName == null) {
+ if (file != null)
+ fileName = file.getName();
+ else
+ fileName = "Untitled.md";
+ }
+ if (!filePath.endsWith("/"))
+ filePath += "/";
+ final boolean result;
+ new AsyncTask() {
+ @Override
+ protected Void doInBackground(String... strings) {
+ try {
+ PrintWriter writer = new PrintWriter(strings[0], "UTF-8");
+ writer.write(markdownLiveData.getValue());
+ } catch (IOException e) {
+ Log.e(TAG, "Error saving file: ", e);
+ }
+ return null;
+ }
+ }.execute(filePath + fileName);
+ return true;
+ }
+
+ public void requestSave(String s) {
+ // Do something to save the file?
+ }
+
+ public String getMarkdown() {
+ return markdownLiveData.getValue();
+ } */
}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/PreviewFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/PreviewFragment.java
deleted file mode 100644
index e04f382..0000000
--- a/app/src/main/java/com/wbrawner/simplemarkdown/PreviewFragment.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.wbrawner.simplemarkdown;
-
-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.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.WebView;
-
-import com.commonsware.cwac.anddown.AndDown;
-
-import org.reactivestreams.Subscriber;
-import org.reactivestreams.Subscription;
-
-import butterknife.BindView;
-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 LifecycleFragment {
- private static final String TAG = PreviewFragment.class.getSimpleName();
- private static final int INTERNET_REQUEST = 0;
- private MarkdownViewModel markdownViewModel;
-
- @BindView(R.id.markdown_view)
- WebView markdownView;
-
- public static final String SCROLL_ACTION = "com.wbrawner.simplemarkdown.scroll";
- public static final String PREVIEW_ACTION = "com.wbrawner.simplemarkdown.preview";
-
- public PreviewFragment() {
- // Required empty public constructor
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- View view = inflater.inflate(R.layout.fragment_preview, container, false);
- ButterKnife.bind(this, view);
- 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) {
- WebView.setWebContentsDebuggingEnabled(true);
- }
- return view;
- }
-}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java b/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java
new file mode 100644
index 0000000..06d60af
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java
@@ -0,0 +1,198 @@
+package com.wbrawner.simplemarkdown.model;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.util.Scanner;
+
+import static android.content.ContentValues.TAG;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+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;
+ private String name;
+ private String path;
+ private String content;
+
+ public MarkdownFile(String name, String path, String content) {
+ this.name = name;
+ this.path = path;
+ this.content = content;
+ }
+
+ public MarkdownFile(String path) {
+ int code = load(path);
+ if (code != SUCCESS) {
+ this.name = path.substring(
+ path.lastIndexOf("/") + 1
+ );
+ this.path = path.substring(
+ 0,
+ path.lastIndexOf("/")
+ );
+ this.content = "";
+ }
+ }
+
+ public MarkdownFile() {
+ this.name = "Untitled.md";
+ this.path = "";
+ this.content = "";
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getFullPath() {
+ String fullPath;
+ if (!this.path.endsWith("/"))
+ fullPath = this.path + "/";
+ else
+ fullPath = this.path;
+ return fullPath + this.name;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public int load(InputStream in) {
+ StringBuilder sb = new StringBuilder();
+ Scanner s = new java.util.Scanner(in).useDelimiter("\\n");
+ while(s.hasNext()) {
+ sb.append(s.next() + "\n");
+ }
+ this.content = sb.toString();
+ return SUCCESS;
+ }
+
+ public int load(String path) {
+ Log.d(TAG, path);
+ int code;
+ File markdownFile = new File(path);
+ if (markdownFile.exists() && markdownFile.canRead()) {
+ BufferedReader reader = null;
+ try {
+ this.name = markdownFile.getName();
+ this.path = markdownFile.getPath();
+ StringBuilder sb = new StringBuilder();
+ String line;
+ reader = new BufferedReader(new FileReader(markdownFile));
+ 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() {
+ if (!parametersOk())
+ return PARAMETERS_MISSING;
+ return load(getFullPath());
+ }
+
+ public int save(String path) {
+ int code;
+ File markdownFile = new File(path);
+ if (!markdownFile.exists()) {
+ try {
+ markdownFile.createNewFile();
+ } catch (IOException e) {
+ return WRITE_ERROR;
+ }
+ }
+ if (markdownFile.canWrite()) {
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(
+ new FileOutputStream(markdownFile)
+ );
+ writer.write(this.content);
+ code = SUCCESS;
+ }
+ catch (IOException e) {
+ code = WRITE_ERROR;
+ }
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ // closing the reader failed
+ }
+ }
+ } else {
+ code = WRITE_ERROR;
+ }
+ return code;
+ }
+
+ public int save() {
+ if (!parametersOk())
+ return PARAMETERS_MISSING;
+ return save(this.getFullPath());
+ }
+
+ public int fileExists(String path) {
+ if (new File(path).exists())
+ return FILE_EXISTS;
+ return FILE_NOT_EXISTS;
+ }
+
+ public int fileExists() {
+ if (parametersOk())
+ return fileExists(getFullPath());
+ return PARAMETERS_MISSING;
+ }
+
+ private boolean parametersOk() {
+ return !this.name.isEmpty() && !this.path.isEmpty();
+ }
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/presentation/LifecyclePresenter.java b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/LifecyclePresenter.java
new file mode 100644
index 0000000..18b15d4
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/LifecyclePresenter.java
@@ -0,0 +1,10 @@
+package com.wbrawner.simplemarkdown.presentation;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public interface LifecyclePresenter {
+ void resume();
+ void pause();
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenter.java b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenter.java
new file mode 100644
index 0000000..c335599
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenter.java
@@ -0,0 +1,24 @@
+package com.wbrawner.simplemarkdown.presentation;
+
+import com.wbrawner.simplemarkdown.view.MarkdownEditView;
+import com.wbrawner.simplemarkdown.view.MarkdownPreviewView;
+
+import java.io.InputStream;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public interface MarkdownPresenter extends LifecyclePresenter {
+ void loadMarkdown(String filePath);
+ void loadMarkdown(InputStream in);
+ void setEditView(MarkdownEditView editView);
+ void setPreviewView(MarkdownPreviewView previewView);
+ void saveMarkdown(String filePath);
+ void onMarkdownEdited();
+ void onMarkdownEdited(String markdown);
+ String getFileName();
+ void setFileName(String name);
+ String getMarkdown();
+ void setMarkdown(String markdown);
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenterImpl.java b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenterImpl.java
new file mode 100644
index 0000000..540d5ee
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/presentation/MarkdownPresenterImpl.java
@@ -0,0 +1,122 @@
+package com.wbrawner.simplemarkdown.presentation;
+
+import com.commonsware.cwac.anddown.AndDown;
+import com.wbrawner.simplemarkdown.model.MarkdownFile;
+import com.wbrawner.simplemarkdown.view.MarkdownEditView;
+import com.wbrawner.simplemarkdown.view.MarkdownPreviewView;
+
+import java.io.InputStream;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public class MarkdownPresenterImpl implements MarkdownPresenter {
+ private MarkdownFile file;
+ private MarkdownEditView editView;
+ private MarkdownPreviewView previewView;
+ private String TAG = MarkdownPresenterImpl.class.getSimpleName();
+
+ public MarkdownPresenterImpl(MarkdownFile file) {
+ this.file = file;
+ }
+
+ @Override
+ public void resume() {}
+
+ @Override
+ public void pause() {
+ saveMarkdown("");
+ }
+
+ @Override
+ public void loadMarkdown(String filePath) {
+ Runnable fileLoader = () -> {
+ int result = file.load(filePath);
+ if (result == MarkdownFile.SUCCESS) {
+ editView.setMarkdown(getMarkdown());
+ onMarkdownEdited();
+ } else {
+ editView.showFileLoadeddError(result);
+ }
+ };
+ fileLoader.run();
+ }
+
+ @Override
+ public void loadMarkdown(InputStream in) {
+ Runnable fileLoader = () -> {
+ int result = file.load(in);
+ if (result == MarkdownFile.SUCCESS) {
+ editView.setMarkdown(getMarkdown());
+ onMarkdownEdited();
+ } else {
+ editView.showFileLoadeddError(result);
+ }
+ };
+ fileLoader.run();
+ }
+
+ @Override
+ public void setEditView(MarkdownEditView editView) {
+ this.editView = editView;
+ }
+
+ @Override
+ public void setPreviewView(MarkdownPreviewView previewView) {
+ this.previewView = previewView;
+ }
+
+ @Override
+ public void saveMarkdown(String filePath) {
+ Runnable fileSaver = () -> {
+ int code;
+ code = file.save(filePath);
+ if (code == MarkdownFile.SUCCESS) {
+ editView.showFileSavedMessage();
+ } else {
+ editView.showFileSavedError(code);
+ }
+ };
+ fileSaver.run();
+ }
+
+ @Override
+ public void onMarkdownEdited(String markdown) {
+ 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;
+ if (previewView != null)
+ previewView.updatePreview(andDown.markdownToHtml(markdown, hoedownFlags, 0));
+ };
+ generateMarkdown.run();
+ }
+
+ @Override
+ public void onMarkdownEdited() {
+ onMarkdownEdited(getMarkdown());
+ }
+
+ @Override
+ public String getFileName() {
+ return file.getName();
+ }
+
+ @Override
+ public void setFileName(String name) {
+ file.setName(name);
+ }
+
+ @Override
+ public String getMarkdown() {
+ return file.getContent();
+ }
+
+ @Override
+ public void setMarkdown(String markdown) {
+ file.setContent(markdown);
+ }
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownEditView.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownEditView.java
new file mode 100644
index 0000000..9b26695
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownEditView.java
@@ -0,0 +1,15 @@
+package com.wbrawner.simplemarkdown.view;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public interface MarkdownEditView {
+ String getMarkdown();
+ void setMarkdown(String markdown);
+
+ void showFileSavedMessage();
+ void showFileSavedError(int code);
+ void showFileLoadedMessage();
+ void showFileLoadeddError(int code);
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownPreviewView.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownPreviewView.java
new file mode 100644
index 0000000..f23179b
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/MarkdownPreviewView.java
@@ -0,0 +1,9 @@
+package com.wbrawner.simplemarkdown.view;
+
+/**
+ * Created by billy on 8/22/17.
+ */
+
+public interface MarkdownPreviewView {
+ void updatePreview(String html);
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java
new file mode 100644
index 0000000..9207ac8
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java
@@ -0,0 +1,236 @@
+package com.wbrawner.simplemarkdown.view.activity;
+
+import android.Manifest;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.database.Cursor;
+import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.provider.OpenableColumns;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.text.InputType;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.wbrawner.simplemarkdown.MarkdownApplication;
+import com.wbrawner.simplemarkdown.R;
+import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
+import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter;
+import java.io.InputStream;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class MainActivity extends AppCompatActivity
+ implements ActivityCompat.OnRequestPermissionsResultCallback {
+
+ public static final int WRITE_PERMISSION_REQUEST = 0;
+ private static final int OPEN_FILE_REQUEST = 1;
+ public static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider";
+
+ @Inject
+ MarkdownPresenter presenter;
+
+ @BindView(R.id.pager)
+ ViewPager pager;
+ @BindView(R.id.layout_tab)
+ TabLayout tabLayout;
+
+ private static final String TAG = MainActivity.class.getSimpleName();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ ((MarkdownApplication) getApplication()).getComponent().inject(this);
+
+ // Reset the background color
+ getWindow().setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
+ ButterKnife.bind(this);
+ pager.setAdapter(
+ new EditPagerAdapter(getSupportFragmentManager(), MainActivity.this)
+ );
+ pager.setPageMargin(1);
+ pager.setPageMarginDrawable(R.color.colorAccent);
+ Intent intent = getIntent();
+ if (intent != null && !intent.getAction().equals(Intent.ACTION_MAIN) && intent.getData() != null) {
+ loadFromUri(intent.getData());
+ }
+ if (getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_LANDSCAPE) {
+ tabLayout.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
+ tabLayout.setVisibility(View.GONE);
+ else
+ tabLayout.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_edit, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_save:
+ if (ContextCompat.checkSelfPermission(
+ MainActivity.this,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE
+ ) == PackageManager.PERMISSION_GRANTED)
+ showSaveDialog();
+ else {
+ if (Build.VERSION.SDK_INT >= 23) {
+ requestPermissions(
+ new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ WRITE_PERMISSION_REQUEST
+ );
+ }
+ }
+ break;
+ case R.id.action_share:
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_TEXT, presenter.getMarkdown());
+ shareIntent.setType("text/plain");
+ startActivity(Intent.createChooser(
+ shareIntent,
+ getString(R.string.share_file)
+ ));
+ break;
+ case R.id.action_load:
+ requestOpen();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void showSaveDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.action_save);
+
+ final EditText input = new EditText(this);
+ input.setInputType(InputType.TYPE_CLASS_TEXT);
+ input.setHint(R.string.hint_filename);
+ input.setText(presenter.getFileName());
+ builder.setView(input);
+
+ builder.setPositiveButton("OK", (dialog, which) -> {
+ if (input.getText().length() > 0) {
+ presenter.setFileName(input.getText().toString());
+ setTitle(input.getText());
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ String path = Environment.getExternalStorageDirectory() + "/" +
+ Environment.DIRECTORY_DOCUMENTS + "/" + input.getText();
+ presenter.saveMarkdown(path);
+ }
+ }
+ });
+ builder.setNegativeButton("Cancel", (dialog, which) -> {
+ dialog.cancel();
+ });
+
+ builder.show();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case WRITE_PERMISSION_REQUEST: {
+ // If request is cancelled, the result arrays are empty.
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // Permission granted, open file save dialog
+ showSaveDialog();
+ } else {
+ // Permission denied, do nothing
+ Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT)
+ .show();
+ }
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (pager.getCurrentItem() == EditPagerAdapter.FRAGMENT_EDIT)
+ super.onBackPressed();
+ else
+ pager.setCurrentItem(EditPagerAdapter.FRAGMENT_EDIT);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case OPEN_FILE_REQUEST:
+ if (resultCode == RESULT_OK) {
+ loadFromUri(data.getData());
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ private void loadFromUri(Uri fileUri) {
+ try {
+ InputStream in =
+ getContentResolver().openInputStream(fileUri);
+ Cursor retCur = getContentResolver()
+ .query(fileUri, null, null, null, null);
+ if (retCur != null) {
+ int nameIndex = retCur
+ .getColumnIndex(OpenableColumns.DISPLAY_NAME);
+ retCur.moveToFirst();
+ presenter.setFileName(retCur.getString(nameIndex));
+ }
+ presenter.loadMarkdown(in);
+ } catch (Exception e) {
+ Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT)
+ .show();
+ }
+
+ }
+
+ private void requestOpen() {
+ Intent openIntent = new Intent(Intent.ACTION_GET_CONTENT);
+ openIntent.setType("text/*");
+ openIntent.addCategory(Intent.CATEGORY_OPENABLE);
+ try {
+ startActivityForResult(
+ Intent.createChooser(
+ openIntent,
+ getString(R.string.open_file)
+ ),
+ OPEN_FILE_REQUEST
+ );
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(MainActivity.this, R.string.no_filebrowser, Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/EditPagerAdapter.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/adapter/EditPagerAdapter.java
similarity index 77%
rename from app/src/main/java/com/wbrawner/simplemarkdown/EditPagerAdapter.java
rename to app/src/main/java/com/wbrawner/simplemarkdown/view/adapter/EditPagerAdapter.java
index f2e52cc..9b10d5e 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/EditPagerAdapter.java
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/adapter/EditPagerAdapter.java
@@ -1,4 +1,4 @@
-package com.wbrawner.simplemarkdown;
+package com.wbrawner.simplemarkdown.view.adapter;
/**
* Created by billy on 7/29/2017.
@@ -10,11 +10,15 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
-import static com.wbrawner.simplemarkdown.MainActivity.FRAGMENT_EDIT;
-import static com.wbrawner.simplemarkdown.MainActivity.FRAGMENT_PREVIEW;
-import static com.wbrawner.simplemarkdown.MainActivity.NUM_PAGES;
+import com.wbrawner.simplemarkdown.R;
+import com.wbrawner.simplemarkdown.view.fragment.EditFragment;
+import com.wbrawner.simplemarkdown.view.fragment.PreviewFragment;
+
+public class EditPagerAdapter extends FragmentPagerAdapter {
+ public static final int FRAGMENT_EDIT = 0;
+ public static final int FRAGMENT_PREVIEW = 1;
+ public static final int NUM_PAGES = 2;
-class EditPagerAdapter extends FragmentPagerAdapter {
private Context mContext;
public EditPagerAdapter(FragmentManager fm, Context context) {
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java
new file mode 100644
index 0000000..303f27a
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java
@@ -0,0 +1,112 @@
+package com.wbrawner.simplemarkdown.view.fragment;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.jakewharton.rxbinding2.widget.RxTextView;
+import com.wbrawner.simplemarkdown.MarkdownApplication;
+import com.wbrawner.simplemarkdown.R;
+import com.wbrawner.simplemarkdown.model.MarkdownFile;
+import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
+import com.wbrawner.simplemarkdown.view.MarkdownEditView;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+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();
+
+ @Inject
+ MarkdownPresenter presenter;
+
+ @BindView(R.id.markdown_edit)
+ EditText markdownEditor;
+
+ public EditFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.fragment_edit, container, false);
+ ButterKnife.bind(this, view);
+ ((MarkdownApplication) getActivity().getApplication()).getComponent().inject(this);
+
+ Observable obs = RxTextView.textChanges(markdownEditor)
+ .debounce(50, TimeUnit.MILLISECONDS).map(CharSequence::toString);
+ obs.subscribeOn(Schedulers.io());
+ obs.observeOn(AndroidSchedulers.mainThread());
+ obs.subscribe(markdown -> {
+ presenter.onMarkdownEdited(markdown);
+ });
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ presenter.setEditView(this);
+ setMarkdown(presenter.getMarkdown());
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ presenter.setEditView(null);
+ }
+
+ @Override
+ public String getMarkdown() {
+ return markdownEditor.getText().toString();
+ }
+
+ @Override
+ public void showFileSavedMessage() {
+ Toast.makeText(getActivity(), R.string.file_saved, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ 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();
+ }
+
+ @Override
+ public void showFileLoadedMessage() {
+ Toast.makeText(getActivity(), R.string.file_loaded, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void showFileLoadeddError(int code) {
+ String message = "";
+ Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void setMarkdown(String markdown) {
+ markdownEditor.setText(markdown);
+ }
+}
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java
new file mode 100644
index 0000000..89fd514
--- /dev/null
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java
@@ -0,0 +1,74 @@
+package com.wbrawner.simplemarkdown.view.fragment;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+
+import com.wbrawner.simplemarkdown.MarkdownApplication;
+import com.wbrawner.simplemarkdown.R;
+import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
+import com.wbrawner.simplemarkdown.view.MarkdownPreviewView;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class PreviewFragment extends Fragment implements MarkdownPreviewView {
+ private static final String TAG = PreviewFragment.class.getSimpleName();
+
+ @Inject
+ MarkdownPresenter presenter;
+
+ @BindView(R.id.markdown_view)
+ WebView markdownPreview;
+
+ public PreviewFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.fragment_preview, container, false);
+ ButterKnife.bind(this, view);
+ ((MarkdownApplication) getActivity().getApplication()).getComponent().inject(this);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ WebView.setWebContentsDebuggingEnabled(true);
+ }
+ return view;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ }
+
+
+
+ @Override
+ public void updatePreview(String html) {
+ markdownPreview.post(() -> {
+ markdownPreview.loadData(html, "text/html", "UTF-8");
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ presenter.setPreviewView(this);
+ presenter.onMarkdownEdited();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ presenter.setPreviewView(null);
+ }
+}
diff --git a/app/src/main/res/layout/fragment_edit.xml b/app/src/main/res/layout/fragment_edit.xml
index 6b97ca6..d257fe0 100644
--- a/app/src/main/res/layout/fragment_edit.xml
+++ b/app/src/main/res/layout/fragment_edit.xml
@@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="com.wbrawner.simplemarkdown.EditFragment">
+ tools:context="com.wbrawner.simplemarkdown.view.fragment.EditFragment">
+ tools:context="com.wbrawner.simplemarkdown.view.fragment.PreviewFragment">