diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index b1759b1..4264c2f 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,17 +1,17 @@
-
+
-
+
-
-
+
+
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/wntr/mdeditor/MainActivity.kt b/app/src/main/java/org/wntr/mdeditor/MainActivity.kt
index 7e3db00..8e878e3 100644
--- a/app/src/main/java/org/wntr/mdeditor/MainActivity.kt
+++ b/app/src/main/java/org/wntr/mdeditor/MainActivity.kt
@@ -48,6 +48,7 @@ import java.io.InputStreamReader
import java.lang.Thread.sleep
import java.net.URLDecoder
import java.time.Instant
+import kotlin.concurrent.fixedRateTimer
class MainActivity : AppCompatActivity() {
@@ -62,8 +63,8 @@ class MainActivity : AppCompatActivity() {
var metaData = mdMeta()
var mdToAppend: String = ""
var thisFileUri: Uri? = null
+ var truncate = false
lateinit var tempFile: File
- var emptyFile = false
lateinit var pickMultipleVisualMedia: ActivityResultLauncher
lateinit var ghostSettings: ActivityResultLauncher
lateinit var ghostMetaData: ActivityResultLauncher
@@ -72,6 +73,7 @@ class MainActivity : AppCompatActivity() {
var ghostConnection = false
lateinit var credManager: CredentialManager
var intentScheme = "none"
+ var lastSaved = Instant.now().toEpochMilli()
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -120,7 +122,7 @@ class MainActivity : AppCompatActivity() {
@JavascriptInterface
fun triggerOpenFile() {
- openFile(thisFileUri!!)
+ openFile()
}
@JavascriptInterface
@@ -145,7 +147,7 @@ class MainActivity : AppCompatActivity() {
@JavascriptInterface
fun triggerDisplayName(): String {
- return getDisplayName()
+ return getDisplayName(thisFileUri)
}
@JavascriptInterface
@@ -172,6 +174,14 @@ class MainActivity : AppCompatActivity() {
Log.i(javaClass.simpleName,"delivering cursor: $cursor")
return cursor.toString()
}
+
+ @JavascriptInterface
+ fun toggleBar() {
+ this@MainActivity.runOnUiThread({
+ if (supportActionBar!!.isShowing) supportActionBar!!.hide()
+ else supportActionBar!!.show()
+ })
+ }
}
webView.addJavascriptInterface(jsi, "Android")
@@ -200,6 +210,18 @@ class MainActivity : AppCompatActivity() {
ghostMetaData = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
saveFile()
}
+ fixedRateTimer("timer",true,0,5000){
+ this@MainActivity.runOnUiThread {
+ webView.evaluateJavascript("easyMDE.codemirror.doc.isClean();", {
+ if (it == "false" && thisFileUri != null) {
+ saveFile()
+ this@MainActivity.runOnUiThread {
+ webView.evaluateJavascript("easyMDE.codemirror.doc.markClean();", {})
+ }
+ }
+ })
+ }
+ }
}
override fun onResume() {
@@ -305,6 +327,20 @@ class MainActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
when (id) {
+ R.id.new_file -> {
+ truncate = true
+ selectFileForSaveAs()
+ }
+
+ R.id.open_file -> {
+ openFile()
+ }
+
+ R.id.save_file -> {
+ saveFile()
+ selectFileForSaveAs()
+ }
+
R.id.push_ghost -> {
webView.evaluateJavascript("getHtml();", {
val msg = URLDecoder.decode(it.removeSurrounding("\""))
@@ -323,7 +359,7 @@ class MainActivity : AppCompatActivity() {
} else {
Log.i(javaClass.simpleName,"posting $msg")
updatePost(
- title = metaData.get("title") ?: getDisplayName(),
+ title = metaData.get("title") ?: getDisplayName(thisFileUri),
author = credManager.username,
html = msg,
id = metaData.getId()!!
@@ -514,7 +550,7 @@ class MainActivity : AppCompatActivity() {
}
fun sendPosting(html: String, author: String): retrofit2.Response {
- val title = metaData.get("title") ?: "test" //getDisplayName()
+ val title = metaData.get("title") ?: "test"
val post = sendPost(title, updated_at = Instant.now().toString(), authors = listOf(author), html, feature_image = metaData.get("feature_image"))
val postings = sendPostList(listOf(post))
var response: retrofit2.Response = retrofit2.Response.error(
@@ -690,33 +726,33 @@ class MainActivity : AppCompatActivity() {
// Create an image file name
val storageDir = File(cacheDir, "html")
storageDir.mkdir()
- tempFile = File(storageDir.path + "/${getDisplayName().split(".")[0]}.html")
+ tempFile = File(storageDir.path + "/${getDisplayName(thisFileUri).split(".")[0]}.html")
if (tempFile.exists()) tempFile.delete()
tempFile.createNewFile()
}
- fun openFile(uri: Uri) {
+ fun openFile() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
- putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
+ putExtra(DocumentsContract.EXTRA_INITIAL_URI, thisFileUri)
type = "text/*"
- getDisplayName().apply { putExtra(Intent.EXTRA_TITLE, getDisplayName()) }
+ getDisplayName(thisFileUri).apply { putExtra(Intent.EXTRA_TITLE, getDisplayName(
+ thisFileUri)) }
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivityForResult(intent, OPEN_FILE)
- Log.i(javaClass.simpleName, "Buffer gelesen")
}
@SuppressLint("Range")
- fun getDisplayName(): String {
+ fun getDisplayName(uri: Uri?): String {
// via: https://stackoverflow.com/questions/5568874/how-to-extract-the-file-name-from-uri-returned-from-intent-action-get-content
var result: String? = null;
- if (thisFileUri == null) return "hauntED.md"
- if (thisFileUri!!.getScheme().equals("content")) {
- val cursor = getContentResolver().query(thisFileUri!!, null, null, null, null);
+ if (uri == null) return "hauntED.md"
+ if (uri!!.getScheme().equals("content")) {
+ val cursor = getContentResolver().query(uri!!, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
@@ -726,7 +762,7 @@ class MainActivity : AppCompatActivity() {
}
}
if (result == null) {
- result = thisFileUri!!.getPath();
+ result = uri!!.getPath();
val cut = result!!.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
@@ -739,7 +775,7 @@ class MainActivity : AppCompatActivity() {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/*"
- putExtra(Intent.EXTRA_TITLE, getDisplayName())
+ putExtra(Intent.EXTRA_TITLE, getDisplayName(thisFileUri))
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
@@ -785,11 +821,9 @@ class MainActivity : AppCompatActivity() {
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
- thisFileUri = uri
+ Log.d(javaClass.simpleName, "Saving to: ${getDisplayName(thisFileUri)}\n${getDisplayName(uri)}")
+ if (getDisplayName(thisFileUri) + " (1)" != getDisplayName(uri)) thisFileUri = uri
saveAs()
-
- webView.evaluateJavascript("easyMDE.codemirror.focus()", ValueCallback() {})
- Log.i(javaClass.simpleName, "file newly written")
}
} else if (requestCode == OPEN_FILE && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { uri ->
@@ -797,8 +831,7 @@ class MainActivity : AppCompatActivity() {
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION and Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
- thisFileUri = uri
- saveMetaToSharedPrefs()
+ readFile(uri)
if (metaData.metaData.get("url") == null) {
deleteVisible = false
@@ -811,12 +844,8 @@ class MainActivity : AppCompatActivity() {
}
}
- fun getFileContents(): String {
- return metaData.toString() + mdeValue
- }
-
- fun saveFile(): Boolean {
- if (thisFileUri == null) return false
+ fun saveFile() {
+ if (thisFileUri == null) return
lateinit var textFile: ParcelFileDescriptor
try {
@@ -835,7 +864,7 @@ class MainActivity : AppCompatActivity() {
).show()
}
)
- return false
+ return
// TODO: implement workaround for this bug. See: https://stackoverflow.com/q/69248596
} catch (e: java.io.FileNotFoundException) {
Log.d(javaClass.simpleName, "File not found. Deleted while loaded?\n${e.stackTraceToString()}")
@@ -849,7 +878,7 @@ class MainActivity : AppCompatActivity() {
}
)
selectFileForSaveAs()
- return false
+ return
}
catch (e: Exception) {
@@ -863,77 +892,80 @@ class MainActivity : AppCompatActivity() {
).show()
}
)
- return false
- }
- /* This block is currently actually not needed as the change logic is made in js */
- //TODO: Rework this for change check on network file provider
- Log.d(
- javaClass.simpleName,
- "Size in cache: ${mdeValue.toByteArray().size} Size on disk: ${textFile.statSize}"
- )
- if (getFileContents().length.toLong() == textFile.statSize) {
- Log.d(javaClass.simpleName, "No change on disk, file not saved.")
- return false
+ return
}
+
try {
- contentResolver.openFileDescriptor(thisFileUri!!, "wt")?.use {
- FileOutputStream(it.fileDescriptor).use {
- it.write(getFileContents().toByteArray())
+ this. runOnUiThread({
+ webView.evaluateJavascript("getValue();") {
+ mdeValue =
+ metaData.toString() + URLDecoder.decode(it.removeSurrounding("\""))
+ if (mdeValue.length.toLong() == textFile.statSize) {
+ Log.d(javaClass.simpleName, "No change on disk, file not saved.")
+ return@evaluateJavascript
+ }
+ contentResolver.openFileDescriptor(thisFileUri!!, "wt")?.use {
+ FileOutputStream(it.fileDescriptor).use {
+ it.write(mdeValue.toByteArray())
+ }
+ }
+ Log.d(javaClass.simpleName, "File saved: ${thisFileUri}")
+ Toast.makeText(
+ this,
+ "File saved.",
+ Toast.LENGTH_SHORT
+ ).show()
+ textFile.close()
}
- }
+ })
} catch (e: Exception) {
Toast.makeText(
this,
"Error during writing.\n$e",
Toast.LENGTH_LONG
).show()
- return false
+ return
}
- Log.d(javaClass.simpleName, "File saved: ${thisFileUri}")
- this.runOnUiThread({
- Toast.makeText(
- this,
- "File saved.",
- Toast.LENGTH_SHORT
- ).show()
- })
- textFile.close()
- return true
}
- private fun saveAs(): Boolean {
- lateinit var textFile: ParcelFileDescriptor
+ private fun saveAs() {
try {
- textFile = contentResolver.openFileDescriptor(thisFileUri!!, "w")!!
- textFile.checkError()
- } catch (e: Exception) {
+ lateinit var textFile: ParcelFileDescriptor
+ try {
+ textFile = contentResolver.openFileDescriptor(thisFileUri!!, "w")!!
+ textFile.checkError()
+ } catch (e: Exception) {
+ Toast.makeText(
+ this,
+ "Problem with accessing file\n$e",
+ Toast.LENGTH_LONG
+ ).show()
+ return
+ }
+ if (truncate) {
+ mdeValue = ""
+ truncate = false
+ }
+ FileOutputStream(textFile.fileDescriptor).use {
+ it.write(mdeValue.toByteArray())
+ }
Toast.makeText(
this,
- "Problem with accessing file\n$e",
+ "File saved.",
Toast.LENGTH_LONG
).show()
- return false
- }
- try {
- FileOutputStream(textFile.fileDescriptor).use {
- it.write(getFileContents().toByteArray())
- }
+ Log.i(javaClass.simpleName, "file newly written")
+ webView.evaluateJavascript("onRead();", ValueCallback() {})
+
+ textFile.close()
+ saveMetaToSharedPrefs()
} catch (e: Exception) {
Toast.makeText(
this,
"Error during writing.\n$e",
Toast.LENGTH_LONG
).show()
- return false
}
- Toast.makeText(
- this,
- "File saved.",
- Toast.LENGTH_LONG
- ).show()
- textFile.close()
- saveMetaToSharedPrefs()
- return true
}
@Throws(IOException::class)
@@ -962,10 +994,6 @@ class MainActivity : AppCompatActivity() {
Toast.LENGTH_LONG
).show()
})
-/*
- openFile(uri)
- return false
-*/
}
try {
contentResolver.openInputStream(uri)?.use { inputStream ->
@@ -1004,9 +1032,11 @@ class MainActivity : AppCompatActivity() {
})
return false
}
-
thisFileUri = uri
saveMetaToSharedPrefs()
+ this.runOnUiThread({
+ webView.evaluateJavascript("onRead();", {})
+ })
return true
}
@@ -1035,7 +1065,7 @@ class MainActivity : AppCompatActivity() {
override fun onPause() {
super.onPause()
/*outState.putString("test", "onSaveInstanceState-String")*/
- webView.evaluateJavascript("saveFile();", ValueCallback() {})
+ saveFile()
webView.evaluateJavascript("easyMDE.codemirror.doc.getCursor();") {
metaData.cursor=it
Log.i(javaClass.simpleName,"Cursor: $it")
diff --git a/app/src/main/res/drawable-hdpi/ic_menu_archive.png b/app/src/main/res/drawable-hdpi/ic_menu_archive.png
new file mode 100644
index 0000000..e2d9bc1
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_menu_archive.png differ
diff --git a/app/src/main/res/drawable-ldpi/ic_menu_archive.png b/app/src/main/res/drawable-ldpi/ic_menu_archive.png
new file mode 100644
index 0000000..719ecd8
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_menu_archive.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_menu_archive.png b/app/src/main/res/drawable-mdpi/ic_menu_archive.png
new file mode 100644
index 0000000..49ac569
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_menu_archive.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_menu_archive.png b/app/src/main/res/drawable-xhdpi/ic_menu_archive.png
new file mode 100644
index 0000000..b1be9d5
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_menu_archive.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_menu_archive.png b/app/src/main/res/drawable-xxhdpi/ic_menu_archive.png
new file mode 100644
index 0000000..a2d93b9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_menu_archive.png differ
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d0c3d78..5ecf787 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -14,7 +14,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constrainedHeight="true"
tools:context=".MainActivity"/>
+ app:layout_constraintTop_toTopOf="parent"/>
\ No newline at end of file
diff --git a/app/src/main/res/menu/ghost_menu.xml b/app/src/main/res/menu/ghost_menu.xml
index 0977109..995a22d 100644
--- a/app/src/main/res/menu/ghost_menu.xml
+++ b/app/src/main/res/menu/ghost_menu.xml
@@ -1,19 +1,31 @@
diff --git a/app/src/main/res/raw/controller.js b/app/src/main/res/raw/controller.js
index 0d4cd30..abe6319 100644
--- a/app/src/main/res/raw/controller.js
+++ b/app/src/main/res/raw/controller.js
@@ -22,14 +22,13 @@ function openFile() {
saveFile()
Android.triggerOpenFile()
onRead()
- easyMDE.codemirror.doc.markClean()
}
function dispatchCut() {
console.log("dispatch cut")
easyMDE.codemirror.getTextArea().dispatchEvent(new Event("cut"))
}
function getValue() {
- return easyMDE.value()
+ return encodeURIComponent(easyMDE.value())
}
function myPreview() {
saveFile()
@@ -48,13 +47,6 @@ function shareText() {
Android.triggerShare(easyMDE.markdown(easyMDE.codemirror.doc.getValue()))
}
-function shareGhostText() {
- saveFile()
- if (confirm('Are you sure you want to publish this?')) {
- Android.triggerGhost(easyMDE.markdown(easyMDE.codemirror.doc.getValue()))
- }
-}
-
function getHtml() {
return encodeURIComponent(easyMDE.markdown(easyMDE.codemirror.doc.getValue()))
}
@@ -67,7 +59,6 @@ function appendText() {
}
}
-
function pasteText() {
data = new DataTransfer()
data.setData("text/plain", Android.getMdToAppend())
@@ -77,6 +68,10 @@ function pasteText() {
document.getElementsByClassName("CodeMirror-scroll")[0].dispatchEvent(event);
saveFile()
}
+function toggleBar() {
+ Android.toggleBar()
+ easyMDE.codemirror.focus()
+}
const easyMDE = new EasyMDE({
spellChecker: false,
@@ -108,66 +103,23 @@ const easyMDE = new EasyMDE({
],
toolbar: [
{
- name: "more",
- className: "fa-solid fa-angles-down",
- title: "more",
- children: [
- {
- name: "saveAs",
- action: saveAs,
- className: "fa fa-star",
- title: "saveAs"
- },
- {
- name: "new",
- action: blankBuffer,
- className: "fa fa-file",
- title: "New"
- },
-/* {
- name: "refresh",
- action: refresh,
- className: "fa fa-refresh",
- title: "Refresh"
- },*/
- {
- name: "day",
- action: () => easyMDE.codemirror.setOption("theme","solarized"),
- className: "fa fa-sun",
- title: "Day Theme"
- },
- {
- name: "night",
- action: () => easyMDE.codemirror.setOption("theme","3024-night"),
- className: "fa fa-moon",
- title: "Night Theme"
- },
- "guide"
- ]
- },
- {
- name: "save",
- action: saveFile,
- className: "fa fa-save",
- title: "Save"
+ name: "day",
+ action: () => easyMDE.codemirror.setOption("theme","solarized"),
+ className: "fa fa-sun",
+ title: "Day Theme"
},
{
- name: "open",
- action: openFile,
- className: "fa-regular fa-folder-open",
- title: "Open"
+ name: "night",
+ action: () => easyMDE.codemirror.setOption("theme","3024-night"),
+ className: "fa fa-moon",
+ title: "Night Theme"
},
+ "guide",
{
name: "share",
action: shareText,
className: "fa fa-share-nodes",
title: "Share"
- },
- {
- name: "shareGhost",
- action: shareGhostText,
- className: "fa fa-ghost",
- title: "Share Ghost"
}, "undo",
{
name: "preview",
@@ -176,7 +128,13 @@ const easyMDE = new EasyMDE({
title: "Preview",
noDisable: true
},"redo",
- "bold", "italic","link","code"
+ "bold", "italic","link","code",
+ {
+ name: "toggle",
+ action: toggleBar,
+ className: "fa fa-expand",
+ title: "Toggle Bar",
+ }
]
});
-onRead();
+onRead();
\ No newline at end of file