Clean up much of the Kotlin usage and remove RxJava
This commit is contained in:
parent
e00d43f93c
commit
829dc11c12
11 changed files with 277 additions and 381 deletions
|
@ -39,7 +39,6 @@ android {
|
||||||
applicationId "com.wbrawner.simplemarkdown"
|
applicationId "com.wbrawner.simplemarkdown"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
multiDexEnabled true
|
|
||||||
versionCode 20
|
versionCode 20
|
||||||
versionName "0.7.0"
|
versionName "0.7.0"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
@ -75,7 +74,6 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
def lifecycle_version = "2.0.0"
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation 'org.robolectric:robolectric:4.2'
|
testImplementation 'org.robolectric:robolectric:4.2'
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
@ -95,18 +93,14 @@ dependencies {
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1'
|
||||||
kapt 'com.google.dagger:dagger-android-processor:2.22.1'
|
kapt 'com.google.dagger:dagger-android-processor:2.22.1'
|
||||||
kapt 'com.google.dagger:dagger-compiler:2.22.1'
|
kapt 'com.google.dagger:dagger-compiler:2.22.1'
|
||||||
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
|
|
||||||
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
|
|
||||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
|
||||||
implementation 'io.reactivex.rxjava2:rxjava:2.2.7'
|
|
||||||
implementation 'com.google.firebase:firebase-core:17.0.1'
|
implementation 'com.google.firebase:firebase-core:17.0.1'
|
||||||
implementation 'com.android.billingclient:billing:1.2'
|
implementation 'com.android.billingclient:billing:1.2'
|
||||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
|
||||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
|
|
||||||
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
|
|
||||||
implementation "androidx.core:core-ktx:1.0.2"
|
implementation "androidx.core:core-ktx:1.0.2"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
def coroutines_version = "1.3.0-RC2"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
|
||||||
implementation 'eu.crydee:syllable-counter:4.0.2'
|
implementation 'eu.crydee:syllable-counter:4.0.2'
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,37 +3,37 @@ package com.wbrawner.simplemarkdown.presentation
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownEditView
|
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownPreviewView
|
|
||||||
|
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
interface MarkdownPresenter {
|
interface MarkdownPresenter {
|
||||||
var fileName: String
|
var fileName: String
|
||||||
var markdown: String
|
var markdown: String
|
||||||
fun loadFromUri(context: Context, fileUri: Uri)
|
var editView: MarkdownEditView?
|
||||||
|
var previewView: MarkdownPreviewView?
|
||||||
fun loadMarkdown(
|
suspend fun loadFromUri(context: Context, fileUri: Uri): String?
|
||||||
|
suspend fun loadMarkdown(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
`in`: InputStream,
|
`in`: InputStream,
|
||||||
listener: FileLoadedListener? = null,
|
|
||||||
replaceCurrentFile: Boolean = true
|
replaceCurrentFile: Boolean = true
|
||||||
)
|
): String?
|
||||||
|
|
||||||
fun newFile(newName: String)
|
fun newFile(newName: String)
|
||||||
fun setEditView(editView: MarkdownEditView)
|
suspend fun saveMarkdown(name: String, outputStream: OutputStream): Boolean
|
||||||
fun setPreviewView(previewView: MarkdownPreviewView)
|
|
||||||
fun saveMarkdown(listener: MarkdownSavedListener, name: String, outputStream: OutputStream)
|
|
||||||
fun onMarkdownEdited(markdown: String? = null)
|
fun onMarkdownEdited(markdown: String? = null)
|
||||||
fun generateHTML(markdown: String? = null): String
|
fun generateHTML(markdown: String = ""): String
|
||||||
|
|
||||||
interface FileLoadedListener {
|
|
||||||
fun onSuccess(markdown: String)
|
|
||||||
fun onError()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MarkdownSavedListener {
|
interface MarkdownEditView {
|
||||||
fun saveComplete(success: Boolean)
|
var markdown: String
|
||||||
|
fun setTitle(title: String)
|
||||||
|
|
||||||
|
fun onFileSaved(success: Boolean)
|
||||||
|
|
||||||
|
fun onFileLoaded(success: Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MarkdownPreviewView {
|
||||||
|
fun updatePreview(html: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,163 +2,126 @@ package com.wbrawner.simplemarkdown.presentation
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Handler
|
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
import com.commonsware.cwac.anddown.AndDown
|
import com.commonsware.cwac.anddown.AndDown
|
||||||
import com.wbrawner.simplemarkdown.model.MarkdownFile
|
import com.wbrawner.simplemarkdown.model.MarkdownFile
|
||||||
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownEditView
|
import kotlinx.coroutines.Dispatchers
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownPreviewView
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class MarkdownPresenterImpl @Inject
|
class MarkdownPresenterImpl @Inject constructor(private val errorHandler: ErrorHandler) : MarkdownPresenter {
|
||||||
constructor(private val errorHandler: ErrorHandler) : MarkdownPresenter {
|
|
||||||
private val fileLock = Any()
|
|
||||||
private var file: MarkdownFile? = null
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var editView: MarkdownEditView? = null
|
private var file: MarkdownFile = MarkdownFile()
|
||||||
@Volatile
|
@Volatile
|
||||||
private var previewView: MarkdownPreviewView? = null
|
override var editView: MarkdownEditView? = null
|
||||||
private val fileHandler = Handler()
|
set(value) {
|
||||||
|
field = value
|
||||||
|
onMarkdownEdited(null)
|
||||||
|
}
|
||||||
|
@Volatile
|
||||||
|
override var previewView: MarkdownPreviewView? = null
|
||||||
|
|
||||||
override var fileName: String
|
override var fileName: String
|
||||||
get() = synchronized(fileLock) {
|
get() = file.name
|
||||||
return file!!.name
|
set(name) {
|
||||||
}
|
file.name = name
|
||||||
set(name) = synchronized(fileLock) {
|
|
||||||
file!!.name = name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override var markdown: String
|
override var markdown: String
|
||||||
get() = synchronized(fileLock) {
|
get() = file.content
|
||||||
return file!!.content
|
set(markdown) {
|
||||||
}
|
file.content = markdown
|
||||||
set(markdown) = synchronized(fileLock) {
|
|
||||||
file!!.content = markdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
override suspend fun loadMarkdown(
|
||||||
synchronized(fileLock) {
|
|
||||||
this.file = MarkdownFile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadMarkdown(
|
|
||||||
fileName: String,
|
fileName: String,
|
||||||
`in`: InputStream,
|
`in`: InputStream,
|
||||||
listener: MarkdownPresenter.FileLoadedListener?,
|
|
||||||
replaceCurrentFile: Boolean
|
replaceCurrentFile: Boolean
|
||||||
) {
|
): String? {
|
||||||
fileHandler.post {
|
|
||||||
val tmpFile = MarkdownFile()
|
val tmpFile = MarkdownFile()
|
||||||
if (tmpFile.load(fileName, `in`)) {
|
withContext(Dispatchers.IO) {
|
||||||
if (listener != null) {
|
if (!tmpFile.load(fileName, `in`)) {
|
||||||
val html = generateHTML(tmpFile.content)
|
throw RuntimeException("Failed to load markdown")
|
||||||
listener.onSuccess(html)
|
}
|
||||||
}
|
}
|
||||||
if (replaceCurrentFile) {
|
if (replaceCurrentFile) {
|
||||||
synchronized(fileLock) {
|
|
||||||
this.file = tmpFile
|
this.file = tmpFile
|
||||||
val currentEditView = editView
|
editView?.let {
|
||||||
if (currentEditView != null) {
|
it.onFileLoaded(true)
|
||||||
currentEditView.onFileLoaded(true)
|
it.setTitle(fileName)
|
||||||
currentEditView.setTitle(fileName)
|
it.markdown = file.content
|
||||||
currentEditView.markdown = this.file!!.content
|
onMarkdownEdited(file.content)
|
||||||
onMarkdownEdited(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
listener?.onError()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return generateHTML(tmpFile.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun newFile(newName: String) {
|
override fun newFile(newName: String) {
|
||||||
synchronized(fileLock) {
|
editView?.let {
|
||||||
val currentEditView = editView
|
file.content = it.markdown
|
||||||
if (currentEditView != null) {
|
it.setTitle(newName)
|
||||||
file!!.content = currentEditView.markdown
|
it.markdown = ""
|
||||||
currentEditView.setTitle(newName)
|
|
||||||
currentEditView.markdown = ""
|
|
||||||
}
|
}
|
||||||
file = MarkdownFile(newName, "")
|
file = MarkdownFile(newName, "")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun setEditView(editView: MarkdownEditView) {
|
override suspend fun saveMarkdown(name: String, outputStream: OutputStream): Boolean {
|
||||||
this.editView = editView
|
val result = withContext(Dispatchers.IO) {
|
||||||
onMarkdownEdited(null)
|
file.save(name, outputStream)
|
||||||
}
|
}
|
||||||
|
editView?.let {
|
||||||
override fun setPreviewView(previewView: MarkdownPreviewView) {
|
it.setTitle(file.name)
|
||||||
this.previewView = previewView
|
it.onFileSaved(result)
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
override fun saveMarkdown(listener: MarkdownPresenter.MarkdownSavedListener, name: String, outputStream: OutputStream) {
|
|
||||||
val fileSaver = {
|
|
||||||
val result: Boolean
|
|
||||||
synchronized(fileLock) {
|
|
||||||
result = file!!.save(name, outputStream)
|
|
||||||
}
|
|
||||||
listener?.saveComplete(result)
|
|
||||||
val currentEditView = editView
|
|
||||||
if (currentEditView != null) {
|
|
||||||
synchronized(fileLock) {
|
|
||||||
currentEditView.setTitle(file!!.name)
|
|
||||||
}
|
|
||||||
currentEditView.onFileSaved(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileHandler.post(fileSaver)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMarkdownEdited(markdown: String?) {
|
override fun onMarkdownEdited(markdown: String?) {
|
||||||
this.markdown = markdown ?: file?.content ?: ""
|
this.markdown = markdown ?: file.content
|
||||||
fileHandler.post {
|
previewView?.updatePreview(generateHTML(this.markdown))
|
||||||
val currentPreviewView = previewView
|
|
||||||
currentPreviewView?.updatePreview(generateHTML(null))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateHTML(markdown: String?): String {
|
override fun generateHTML(markdown: String): String {
|
||||||
val andDown = AndDown()
|
return AndDown().markdownToHtml(markdown, HOEDOWN_FLAGS, 0)
|
||||||
val HOEDOWN_FLAGS = AndDown.HOEDOWN_EXT_STRIKETHROUGH or AndDown.HOEDOWN_EXT_TABLES or
|
|
||||||
AndDown.HOEDOWN_EXT_UNDERLINE or AndDown.HOEDOWN_EXT_SUPERSCRIPT or
|
|
||||||
AndDown.HOEDOWN_EXT_FENCED_CODE
|
|
||||||
return andDown.markdownToHtml(markdown, HOEDOWN_FLAGS, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadFromUri(context: Context, fileUri: Uri) {
|
override suspend fun loadFromUri(context: Context, fileUri: Uri): String? {
|
||||||
try {
|
return try {
|
||||||
val `in` = context.contentResolver.openInputStream(fileUri)
|
|
||||||
var fileName: String? = null
|
var fileName: String? = null
|
||||||
if ("content" == fileUri.scheme) {
|
if ("content" == fileUri.scheme) {
|
||||||
val retCur = context.contentResolver
|
context.contentResolver
|
||||||
.query(fileUri, null, null, null, null)
|
.query(
|
||||||
if (retCur != null) {
|
fileUri,
|
||||||
val nameIndex = retCur
|
null,
|
||||||
.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
null,
|
||||||
retCur.moveToFirst()
|
null,
|
||||||
fileName = retCur.getString(nameIndex)
|
null
|
||||||
retCur.close()
|
)
|
||||||
|
?.use {
|
||||||
|
val nameIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
|
it.moveToFirst()
|
||||||
|
fileName = it.getString(nameIndex)
|
||||||
}
|
}
|
||||||
} else if ("file" == fileUri.scheme) {
|
} else if ("file" == fileUri.scheme) {
|
||||||
fileName = fileUri.lastPathSegment
|
fileName = fileUri.lastPathSegment
|
||||||
}
|
}
|
||||||
if (fileName == null) {
|
val inputStream = context.contentResolver.openInputStream(fileUri) ?: return null
|
||||||
fileName = "Untitled.md"
|
loadMarkdown(fileName ?: "Untitled.md", inputStream, true)
|
||||||
}
|
|
||||||
loadMarkdown(fileName, `in`!!, null, true)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorHandler.reportException(e)
|
errorHandler.reportException(e)
|
||||||
val currentEditView = editView
|
editView?.onFileLoaded(false)
|
||||||
currentEditView?.onFileLoaded(false)
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HOEDOWN_FLAGS = AndDown.HOEDOWN_EXT_STRIKETHROUGH or AndDown.HOEDOWN_EXT_TABLES or
|
||||||
|
AndDown.HOEDOWN_EXT_UNDERLINE or AndDown.HOEDOWN_EXT_SUPERSCRIPT or
|
||||||
|
AndDown.HOEDOWN_EXT_FENCED_CODE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.utility;
|
|
||||||
|
|
||||||
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
|
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
|
||||||
import io.reactivex.Observer;
|
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
|
|
||||||
public class MarkdownObserver implements Observer<String> {
|
|
||||||
private MarkdownPresenter presenter;
|
|
||||||
private Observable<String> obs;
|
|
||||||
|
|
||||||
public MarkdownObserver(MarkdownPresenter presenter, Observable<String> obs) {
|
|
||||||
this.presenter = presenter;
|
|
||||||
this.obs = obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(Disposable d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(String markdown) {
|
|
||||||
presenter.onMarkdownEdited(markdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
System.err.println("An error occurred while handling the markdown");
|
|
||||||
e.printStackTrace();
|
|
||||||
// TODO: report this?
|
|
||||||
obs.subscribe(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.utility;
|
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.style.BackgroundColorSpan;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.wbrawner.simplemarkdown.model.Readability;
|
|
||||||
import com.wbrawner.simplemarkdown.model.Sentence;
|
|
||||||
|
|
||||||
import io.reactivex.Observer;
|
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
|
|
||||||
public class ReadabilityObserver implements Observer<String> {
|
|
||||||
private EditText text;
|
|
||||||
private String previousValue = "";
|
|
||||||
|
|
||||||
public ReadabilityObserver(EditText text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(Disposable d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(String markdown) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
if (markdown.length() < 1) return;
|
|
||||||
if (previousValue.equals(markdown)) return;
|
|
||||||
Readability readability = new Readability(markdown);
|
|
||||||
SpannableString span = new SpannableString(markdown);
|
|
||||||
for (Sentence sentence : readability.sentences()) {
|
|
||||||
int color = Color.TRANSPARENT;
|
|
||||||
if (sentence.syllableCount() > 25) color = Color.argb(100, 229, 232, 42);
|
|
||||||
if (sentence.syllableCount() > 35) color = Color.argb(100, 193, 66, 66);
|
|
||||||
span.setSpan(new BackgroundColorSpan(color), sentence.start(), sentence.end(), 0);
|
|
||||||
}
|
|
||||||
text.setTextKeepState(span, TextView.BufferType.SPANNABLE);
|
|
||||||
previousValue = markdown;
|
|
||||||
long timeTakenMs = System.currentTimeMillis() - start;
|
|
||||||
Log.d("SimpleMarkdown", "Handled markdown in " + timeTakenMs + "ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
System.err.println("An error occurred while handling the markdown");
|
|
||||||
e.printStackTrace();
|
|
||||||
// TODO: report this?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view
|
|
||||||
|
|
||||||
interface MarkdownEditView {
|
|
||||||
var markdown: String
|
|
||||||
fun setTitle(title: String)
|
|
||||||
|
|
||||||
fun onFileSaved(success: Boolean)
|
|
||||||
|
|
||||||
fun onFileLoaded(success: Boolean)
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view
|
|
||||||
|
|
||||||
interface MarkdownPreviewView {
|
|
||||||
fun updatePreview(html: String)
|
|
||||||
}
|
|
|
@ -24,19 +24,20 @@ import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
import com.wbrawner.simplemarkdown.utility.Utils
|
import com.wbrawner.simplemarkdown.utility.Utils
|
||||||
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.InputStream
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback, CoroutineScope {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: MarkdownPresenter
|
lateinit var presenter: MarkdownPresenter
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var errorHandler: ErrorHandler
|
lateinit var errorHandler: ErrorHandler
|
||||||
private var shouldAutoSave = true
|
private var shouldAutoSave = true
|
||||||
private var newFileHandler: NewFileHandler? = null
|
override val coroutineContext: CoroutineContext = Dispatchers.Main
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -65,7 +66,9 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
super.onUserLeaveHint()
|
super.onUserLeaveHint()
|
||||||
if (shouldAutoSave && presenter.markdown.isNotEmpty() && Utils.isAutosaveEnabled(this)) {
|
if (shouldAutoSave && presenter.markdown.isNotEmpty() && Utils.isAutosaveEnabled(this)) {
|
||||||
|
|
||||||
presenter.saveMarkdown(null, "autosave.md", File(filesDir, "autosave.md").outputStream())
|
launch {
|
||||||
|
presenter.saveMarkdown("autosave.md", File(filesDir, "autosave.md").outputStream())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,28 +133,18 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
infoIntent.putExtra("title", title)
|
infoIntent.putExtra("title", title)
|
||||||
var `in`: InputStream? = null
|
launch {
|
||||||
try {
|
try {
|
||||||
val assetManager = assets
|
val inputStream = assets?.open(fileName)
|
||||||
if (assetManager != null) {
|
?: throw RuntimeException("Unable to open stream to $fileName")
|
||||||
`in` = assetManager.open(fileName)
|
val html = presenter.loadMarkdown(fileName, inputStream, false)
|
||||||
}
|
|
||||||
presenter.loadMarkdown(fileName, `in`, object : MarkdownPresenter.FileLoadedListener {
|
|
||||||
override fun onSuccess(html: String) {
|
|
||||||
infoIntent.putExtra("html", html)
|
infoIntent.putExtra("html", html)
|
||||||
startActivity(infoIntent)
|
startActivity(infoIntent)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError() {
|
|
||||||
Toast.makeText(this@MainActivity, R.string.file_load_error, Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}, false)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorHandler.reportException(e)
|
errorHandler.reportException(e)
|
||||||
Toast.makeText(this@MainActivity, R.string.file_load_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@MainActivity, R.string.file_load_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
|
@ -197,12 +190,13 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
|
|
||||||
contentResolver.openFileDescriptor(data.data!!, "r")?.let {
|
contentResolver.openFileDescriptor(data.data!!, "r")?.let {
|
||||||
val fileInput = FileInputStream(it.fileDescriptor)
|
val fileInput = FileInputStream(it.fileDescriptor)
|
||||||
|
launch {
|
||||||
presenter.loadMarkdown(fileName, fileInput)
|
presenter.loadMarkdown(fileName, fileInput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
REQUEST_SAVE_FILE -> {
|
REQUEST_SAVE_FILE -> {
|
||||||
if (resultCode != Activity.RESULT_OK
|
if (resultCode != Activity.RESULT_OK || data?.data == null) {
|
||||||
|| data?.data == null) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,12 +207,15 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
cursor.getString(nameIndex)
|
cursor.getString(nameIndex)
|
||||||
} ?: "Untitled.md"
|
} ?: "Untitled.md"
|
||||||
|
|
||||||
|
launch {
|
||||||
|
val outputStream = contentResolver.openOutputStream(data.data!!)
|
||||||
|
?: throw RuntimeException("Unable to open output stream to save file")
|
||||||
presenter.saveMarkdown(
|
presenter.saveMarkdown(
|
||||||
newFileHandler,
|
|
||||||
fileName,
|
fileName,
|
||||||
contentResolver.openOutputStream(data.data!!)
|
outputStream
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
REQUEST_DARK_MODE -> recreate()
|
REQUEST_DARK_MODE -> recreate()
|
||||||
}
|
}
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
@ -228,11 +225,10 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
AlertDialog.Builder(this)
|
AlertDialog.Builder(this)
|
||||||
.setTitle(R.string.save_changes)
|
.setTitle(R.string.save_changes)
|
||||||
.setMessage(R.string.prompt_save_changes)
|
.setMessage(R.string.prompt_save_changes)
|
||||||
.setNegativeButton(R.string.action_discard) { d, _ ->
|
.setNegativeButton(R.string.action_discard) { _, _ ->
|
||||||
presenter.newFile("Untitled.md")
|
presenter.newFile("Untitled.md")
|
||||||
}
|
}
|
||||||
.setPositiveButton(R.string.action_save) { d, _ ->
|
.setPositiveButton(R.string.action_save) { _, _ ->
|
||||||
newFileHandler = NewFileHandler()
|
|
||||||
requestFileOp(REQUEST_SAVE_FILE)
|
requestFileOp(REQUEST_SAVE_FILE)
|
||||||
}
|
}
|
||||||
.create()
|
.create()
|
||||||
|
@ -283,17 +279,11 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
shouldAutoSave = true
|
shouldAutoSave = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class NewFileHandler : MarkdownPresenter.MarkdownSavedListener {
|
|
||||||
override fun saveComplete(success: Boolean) {
|
override fun onDestroy() {
|
||||||
if (success) {
|
super.onDestroy()
|
||||||
presenter.newFile("Untitled.md")
|
coroutineContext[Job]?.let {
|
||||||
} else {
|
cancel()
|
||||||
Toast.makeText(
|
|
||||||
this@MainActivity,
|
|
||||||
R.string.file_save_error,
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,25 +10,28 @@ import com.wbrawner.simplemarkdown.MarkdownApplication
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
||||||
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class SplashActivity : AppCompatActivity() {
|
class SplashActivity : AppCompatActivity(), CoroutineScope {
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext = Dispatchers.Main
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
internal var presenter: MarkdownPresenter? = null
|
lateinit var presenter: MarkdownPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
internal var errorHandler: ErrorHandler? = null
|
lateinit var errorHandler: ErrorHandler
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
(application as MarkdownApplication).component.inject(this)
|
(application as MarkdownApplication).component.inject(this)
|
||||||
if (sharedPreferences.getBoolean(getString(R.string.error_reports_enabled), true)) {
|
if (sharedPreferences.getBoolean(getString(R.string.error_reports_enabled), true)) {
|
||||||
errorHandler!!.init(this)
|
errorHandler.init(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val darkModeValue = sharedPreferences.getString(
|
val darkModeValue = sharedPreferences.getString(
|
||||||
|
@ -36,11 +39,10 @@ class SplashActivity : AppCompatActivity() {
|
||||||
getString(R.string.pref_value_auto)
|
getString(R.string.pref_value_auto)
|
||||||
)
|
)
|
||||||
|
|
||||||
var darkMode: Int
|
var darkMode = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
AppCompatDelegate.MODE_NIGHT_AUTO
|
||||||
darkMode = AppCompatDelegate.MODE_NIGHT_AUTO
|
|
||||||
} else {
|
} else {
|
||||||
darkMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
}
|
}
|
||||||
|
|
||||||
if (darkModeValue != null && !darkModeValue.isEmpty()) {
|
if (darkModeValue != null && !darkModeValue.isEmpty()) {
|
||||||
|
@ -52,33 +54,26 @@ class SplashActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
AppCompatDelegate.setDefaultNightMode(darkMode)
|
AppCompatDelegate.setDefaultNightMode(darkMode)
|
||||||
|
|
||||||
val intent = intent
|
if (intent?.data != null) {
|
||||||
if (intent != null && intent.data != null) {
|
launch {
|
||||||
presenter!!.loadFromUri(applicationContext, intent.data)
|
presenter.loadFromUri(applicationContext, intent.data!!)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
presenter!!.fileName = "Untitled.md"
|
presenter.fileName = "Untitled.md"
|
||||||
val autosave = File(filesDir, "autosave.md")
|
val autosave = File(filesDir, "autosave.md")
|
||||||
if (autosave.exists()) {
|
if (autosave.exists()) {
|
||||||
try {
|
try {
|
||||||
val fileInputStream = FileInputStream(autosave)
|
launch {
|
||||||
presenter!!.loadMarkdown(
|
presenter.loadMarkdown(
|
||||||
"Untitled.md",
|
"Untitled.md",
|
||||||
fileInputStream,
|
autosave.inputStream(),
|
||||||
object : MarkdownPresenter.FileLoadedListener {
|
|
||||||
override fun onSuccess(markdown: String) {
|
|
||||||
autosave.delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError() {
|
|
||||||
autosave.delete()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
autosave.delete()
|
||||||
|
}
|
||||||
} catch (ignored: FileNotFoundException) {
|
} catch (ignored: FileNotFoundException) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,4 +81,11 @@ class SplashActivity : AppCompatActivity() {
|
||||||
startActivity(startIntent)
|
startActivity(startIntent)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
coroutineContext[Job]?.let {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,126 @@
|
||||||
package com.wbrawner.simplemarkdown.view.fragment
|
package com.wbrawner.simplemarkdown.view.fragment
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.text.style.BackgroundColorSpan
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.ScrollView
|
import android.widget.ScrollView
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
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.model.Readability
|
||||||
|
import com.wbrawner.simplemarkdown.presentation.MarkdownEditView
|
||||||
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
||||||
import com.wbrawner.simplemarkdown.utility.MarkdownObserver
|
|
||||||
import com.wbrawner.simplemarkdown.utility.ReadabilityObserver
|
|
||||||
import com.wbrawner.simplemarkdown.utility.hideKeyboard
|
import com.wbrawner.simplemarkdown.utility.hideKeyboard
|
||||||
import com.wbrawner.simplemarkdown.utility.showKeyboard
|
import com.wbrawner.simplemarkdown.utility.showKeyboard
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownEditView
|
|
||||||
import com.wbrawner.simplemarkdown.view.ViewPagerPage
|
import com.wbrawner.simplemarkdown.view.ViewPagerPage
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import kotlinx.coroutines.*
|
||||||
import io.reactivex.schedulers.Schedulers
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
class EditFragment : Fragment(), MarkdownEditView, ViewPagerPage {
|
class EditFragment : Fragment(), MarkdownEditView, ViewPagerPage, CoroutineScope {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: MarkdownPresenter
|
lateinit var presenter: MarkdownPresenter
|
||||||
private var markdownEditor: EditText? = null
|
private var markdownEditor: EditText? = null
|
||||||
private var markdownEditorScroller: ScrollView? = null
|
private var markdownEditorScroller: ScrollView? = null
|
||||||
|
override var markdown: String
|
||||||
|
get() = markdownEditor?.text?.toString() ?: ""
|
||||||
|
set(value) {
|
||||||
|
markdownEditor?.setText(value)
|
||||||
|
}
|
||||||
|
override val coroutineContext: CoroutineContext = Dispatchers.Main
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?): View? =
|
||||||
// Inflate the layout for this fragment
|
inflater.inflate(R.layout.fragment_edit, container, false)
|
||||||
val view = inflater.inflate(R.layout.fragment_edit, container, false)
|
|
||||||
markdownEditor = view.findViewById(R.id.markdown_edit)
|
|
||||||
markdownEditorScroller = view.findViewById(R.id.markdown_edit_container)
|
|
||||||
val activity = activity
|
|
||||||
if (activity != null) {
|
|
||||||
(activity.application as MarkdownApplication).component.inject(this)
|
|
||||||
}
|
|
||||||
val obs = RxTextView.textChanges(markdownEditor!!)
|
|
||||||
.debounce(50, TimeUnit.MILLISECONDS)
|
|
||||||
.map { it.toString() }
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
obs.subscribe(MarkdownObserver(presenter, obs))
|
|
||||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
|
||||||
val enableReadability = sharedPrefs.getBoolean(getString(R.string.readability_enabled), false)
|
|
||||||
if (enableReadability) {
|
|
||||||
val readabilityObserver = RxTextView.textChanges(markdownEditor!!)
|
|
||||||
.debounce(250, TimeUnit.MILLISECONDS)
|
|
||||||
.map { it.toString() }
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
readabilityObserver.subscribe(ReadabilityObserver(markdownEditor))
|
|
||||||
}
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
presenter.setEditView(this@EditFragment)
|
markdownEditor = view.findViewById(R.id.markdown_edit)
|
||||||
|
markdownEditorScroller = view.findViewById(R.id.markdown_edit_container)
|
||||||
|
markdownEditor?.addTextChangedListener(object : TextWatcher {
|
||||||
|
private var searchFor = ""
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
val searchText = s.toString().trim()
|
||||||
|
if (searchText == searchFor)
|
||||||
|
return
|
||||||
|
|
||||||
|
searchFor = searchText
|
||||||
|
|
||||||
|
launch {
|
||||||
|
delay(50)
|
||||||
|
if (searchText != searchFor)
|
||||||
|
return@launch
|
||||||
|
presenter.onMarkdownEdited(searchText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
|
val enableReadability = sharedPrefs.getBoolean(getString(R.string.readability_enabled), false)
|
||||||
|
if (enableReadability) {
|
||||||
|
markdownEditor?.addTextChangedListener(object : TextWatcher {
|
||||||
|
private var previousValue = ""
|
||||||
|
private var searchFor = ""
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
val searchText = s.toString().trim()
|
||||||
|
if (searchText == searchFor)
|
||||||
|
return
|
||||||
|
|
||||||
|
searchFor = searchText
|
||||||
|
|
||||||
|
launch {
|
||||||
|
delay(250)
|
||||||
|
if (searchText != searchFor)
|
||||||
|
return@launch
|
||||||
|
val start = System.currentTimeMillis()
|
||||||
|
if (markdown.isEmpty()) return@launch
|
||||||
|
if (previousValue == markdown) return@launch
|
||||||
|
val readability = Readability(markdown)
|
||||||
|
val span = SpannableString(markdown)
|
||||||
|
for (sentence in readability.sentences()) {
|
||||||
|
var color = Color.TRANSPARENT
|
||||||
|
if (sentence.syllableCount() > 25) color = Color.argb(100, 229, 232, 42)
|
||||||
|
if (sentence.syllableCount() > 35) color = Color.argb(100, 193, 66, 66)
|
||||||
|
span.setSpan(BackgroundColorSpan(color), sentence.start(), sentence.end(), 0)
|
||||||
|
}
|
||||||
|
markdownEditor?.setTextKeepState(span, TextView.BufferType.SPANNABLE)
|
||||||
|
previousValue = markdown
|
||||||
|
val timeTakenMs = System.currentTimeMillis() - start
|
||||||
|
Log.d("SimpleMarkdown", "Handled markdown in " + timeTakenMs + "ms")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var touchDown = 0L
|
var touchDown = 0L
|
||||||
var oldX = 0f
|
var oldX = 0f
|
||||||
|
@ -92,18 +146,32 @@ class EditFragment : Fragment(), MarkdownEditView, ViewPagerPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||||
|
(activity?.application as? MarkdownApplication)?.component?.inject(this)
|
||||||
|
presenter.editView = this@EditFragment
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
presenter.setEditView(this)
|
presenter.editView = this
|
||||||
markdown = presenter.markdown
|
markdown = presenter.markdown
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
presenter.setEditView(null)
|
presenter.editView = null
|
||||||
markdownEditor?.hideKeyboard()
|
markdownEditor?.hideKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
coroutineContext[Job]?.let {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSelected() {
|
override fun onSelected() {
|
||||||
markdownEditor?.showKeyboard()
|
markdownEditor?.showKeyboard()
|
||||||
}
|
}
|
||||||
|
@ -112,14 +180,6 @@ class EditFragment : Fragment(), MarkdownEditView, ViewPagerPage {
|
||||||
markdownEditor?.hideKeyboard()
|
markdownEditor?.hideKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMarkdown(): String {
|
|
||||||
return markdownEditor!!.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setMarkdown(markdown: String) {
|
|
||||||
markdownEditor?.setText(markdown)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setTitle(title: String) {
|
override fun setTitle(title: String) {
|
||||||
val activity = activity
|
val activity = activity
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import com.wbrawner.simplemarkdown.BuildConfig
|
||||||
import com.wbrawner.simplemarkdown.MarkdownApplication
|
import com.wbrawner.simplemarkdown.MarkdownApplication
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter
|
||||||
import com.wbrawner.simplemarkdown.view.MarkdownPreviewView
|
import com.wbrawner.simplemarkdown.presentation.MarkdownPreviewView
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ class PreviewFragment : Fragment(), MarkdownPreviewView {
|
||||||
}
|
}
|
||||||
@Suppress("ConstantConditionIf")
|
@Suppress("ConstantConditionIf")
|
||||||
val css: String? = if (!BuildConfig.ENABLE_CUSTOM_CSS) {
|
val css: String? = if (!BuildConfig.ENABLE_CUSTOM_CSS) {
|
||||||
getString(defaultCssId)
|
context?.getString(defaultCssId)
|
||||||
} else {
|
} else {
|
||||||
sharedPreferences!!.getString(
|
sharedPreferences!!.getString(
|
||||||
getString(R.string.pref_custom_css),
|
getString(R.string.pref_custom_css),
|
||||||
|
@ -70,7 +70,7 @@ class PreviewFragment : Fragment(), MarkdownPreviewView {
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
presenter.setPreviewView(this)
|
presenter.previewView = this
|
||||||
presenter.onMarkdownEdited()
|
presenter.onMarkdownEdited()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,13 +78,14 @@ class PreviewFragment : Fragment(), MarkdownPreviewView {
|
||||||
markdownPreview?.let {
|
markdownPreview?.let {
|
||||||
(it.parent as ViewGroup).removeView(it)
|
(it.parent as ViewGroup).removeView(it)
|
||||||
it.destroy()
|
it.destroy()
|
||||||
|
markdownPreview = null
|
||||||
}
|
}
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
presenter.setPreviewView(null)
|
presenter.previewView = null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
Loading…
Reference in a new issue