Move image upload to JS part

This commit is contained in:
Jan-Lukas Else 2018-02-12 17:59:30 +01:00
parent fe09e464bf
commit 4ccb45df39
7 changed files with 114 additions and 146 deletions

View File

@ -33,7 +33,5 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'com.github.delight-im:Android-AdvancedWebView:v3.0.0' implementation 'com.github.delight-im:Android-AdvancedWebView:v3.0.0'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0' implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
implementation 'pub.devrel:easypermissions:1.1.3'
implementation 'com.github.kittinunf.fuel:fuel-android:1.12.1' implementation 'com.github.kittinunf.fuel:fuel-android:1.12.1'
} }

View File

@ -1,78 +1,104 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" <link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote-lite.css" rel="stylesheet">
rel="stylesheet"> <style>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script> * {
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> max-width: 100%;
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.css" height: auto;
rel="stylesheet"> word-break: break-all;
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.js"></script> word-break: break-word;
<style> * { max-width: 100%; height: auto; word-break: break-all; word-break: break-word; } }
#summernote {
width: 100%;
height: 100%
}
</style> </style>
</head> </head>
<body> <body>
<div id="summernote" style="width:100%;height:100%"></div> <div id="summernote"></div>
<script> <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
function domToNode(domNode) { <script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote-lite.min.js"></script>
if (domNode.nodeType == domNode.TEXT_NODE) { <script>
return domNode.data; function domToNode(domNode) {
} if (domNode.nodeType == domNode.TEXT_NODE) {
if (domNode.nodeType != domNode.ELEMENT_NODE) { return domNode.data;
return false; }
} if (domNode.nodeType != domNode.ELEMENT_NODE) {
var nodeElement = {}; return false;
nodeElement.tag = domNode.tagName.toLowerCase(); }
for (var i = 0; i < domNode.attributes.length; i++) { var nodeElement = {};
var attr = domNode.attributes[i]; nodeElement.tag = domNode.tagName.toLowerCase();
if (attr.name == 'href' || attr.name == 'src') { for (var i = 0; i < domNode.attributes.length; i++) {
if (!nodeElement.attrs) { var attr = domNode.attributes[i];
nodeElement.attrs = {}; if (attr.name == 'href' || attr.name == 'src') {
} if (!nodeElement.attrs) {
nodeElement.attrs[attr.name] = attr.value; nodeElement.attrs = {};
} }
} nodeElement.attrs[attr.name] = attr.value;
if (domNode.childNodes.length > 0) { }
nodeElement.children = []; }
for (var ii = 0; ii < domNode.childNodes.length; ii++) { if (domNode.childNodes.length > 0) {
var child = domNode.childNodes[ii]; nodeElement.children = [];
nodeElement.children.push(domToNode(child)); for (var ii = 0; ii < domNode.childNodes.length; ii++) {
} var child = domNode.childNodes[ii];
} nodeElement.children.push(domToNode(child));
return nodeElement; }
} }
return nodeElement;
}
function getNodeJson() { function getNodeJson() {
window.android.getText(JSON.stringify(domToNode(document.getElementsByClassName('note-editable')[0]).children)); window.android.getText(JSON.stringify(domToNode(document.getElementsByClassName('note-editable')[0]).children));
} }
</script> function uploadImage(file) {
<script> data = new FormData();
$(document).ready(function () { data.append("FileUpload", file);
$('#summernote').summernote({ $.ajax({
height: 1200, data: data,
focus: true, type: "POST",
placeholder: '', url: "http://telegra.ph/upload",
toolbar: [ cache: false,
// [groupName, [list of button]] contentType: false,
['style', ['bold', 'italic']], processData: false,
['para', ['ul', 'ol']], success: function (data) {
['insert', ['link']], if (data) {
['history', ['undo', 'redo']], $('#summernote').summernote('insertImage', data[0].src);
['other', ['codeview']] }
], }
callbacks: { });
onInit: function (e) { }
$("#summernote").summernote("fullscreen.toggle");
}
}
});
});
</script> $(document).ready(function () {
$('#summernote').summernote({
height: 1200,
focus: true,
placeholder: 'Start writing...',
toolbar: [
['style', ['bold', 'italic', 'underline', 'clear']],
['para', ['ul', 'ol']],
['insert', ['link', 'picture', 'hr']],
['history', ['undo', 'redo']],
['other', ['codeview']]
],
callbacks: {
onInit: function (e) {
$("#summernote").summernote("fullscreen.toggle");
},
onImageUpload: function (files) {
uploadImage(files[0]);
}
}
});
});
</script>
</body> </body>
</html> </html>

View File

@ -4,11 +4,11 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.webkit.JavascriptInterface import android.webkit.JavascriptInterface
import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import im.delight.android.webview.AdvancedWebView
class Editor : WebView { class Editor : AdvancedWebView {
private var getCallback: (json: String?) -> Unit? = {} private var getCallback: (json: String?) -> Unit? = {}
constructor(context: Context) : super(context) { constructor(context: Context) : super(context) {
@ -26,7 +26,6 @@ class Editor : WebView {
@SuppressLint("SetJavaScriptEnabled", "AddJavascriptInterface") @SuppressLint("SetJavaScriptEnabled", "AddJavascriptInterface")
private fun init() { private fun init() {
this.settings.javaScriptEnabled = true this.settings.javaScriptEnabled = true
this.settings.cacheMode = WebSettings.LOAD_NO_CACHE
this.addJavascriptInterface(MyJavaScriptInterface(), "android") this.addJavascriptInterface(MyJavaScriptInterface(), "android")
this.settings.loadWithOverviewMode = true this.settings.loadWithOverviewMode = true
this.settings.useWideViewPort = true this.settings.useWideViewPort = true

View File

@ -8,15 +8,26 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.folderselector.FileChooserDialog
import im.delight.android.webview.AdvancedWebView import im.delight.android.webview.AdvancedWebView
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
import java.io.File
class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserDialog.FileCallback { class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
private val webView: AdvancedWebView? by lazy { findViewById<AdvancedWebView?>(R.id.webView) } private val webView: AdvancedWebView? by lazy {
private val editor: Editor? by lazy { findViewById<Editor?>(R.id.editor) } findViewById<AdvancedWebView?>(R.id.webView)?.apply {
setListener(this@MainActivity, this@MainActivity)
setMixedContentAllowed(true)
setCookiesEnabled(true)
setThirdPartyCookiesEnabled(true)
addPermittedHostname("telegra.ph")
isHorizontalScrollBarEnabled = false
isVerticalScrollBarEnabled = false
overScrollMode = View.OVER_SCROLL_NEVER
}
}
private val editor: Editor? by lazy {
findViewById<Editor?>(R.id.editor)?.apply {
setListener(this@MainActivity, this@MainActivity)
}
}
private var currentUrl = "" private var currentUrl = ""
private var currentPage: TelegraphApi.Page? = null private var currentPage: TelegraphApi.Page? = null
@ -27,16 +38,6 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
webView?.apply {
setListener(this@MainActivity, this@MainActivity)
setMixedContentAllowed(true)
setCookiesEnabled(true)
setThirdPartyCookiesEnabled(true)
addPermittedHostname("telegra.ph")
isHorizontalScrollBarEnabled = false
isVerticalScrollBarEnabled = false
overScrollMode = View.OVER_SCROLL_NEVER
}
if (accessToken().isBlank()) TelegraphApi.createAccount(shortName = "teleposter") { success, account, error -> if (accessToken().isBlank()) TelegraphApi.createAccount(shortName = "teleposter") { success, account, error ->
if (success && account != null && account.accessToken != null) { if (success && account != null && account.accessToken != null) {
saveAccessToken(account.accessToken) saveAccessToken(account.accessToken)
@ -120,17 +121,6 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
} }
} }
@AfterPermissionGranted(100)
private fun uploadImage() {
if (EasyPermissions.hasPermissions(this, "android.permission.READ_EXTERNAL_STORAGE")) {
FileChooserDialog.Builder(this)
.mimeType("image/*")
.show(this)
} else {
EasyPermissions.requestPermissions(this, "", 100, "android.permission.READ_EXTERNAL_STORAGE")
}
}
override fun onPageFinished(url: String?) { override fun onPageFinished(url: String?) {
} }
@ -147,17 +137,6 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
AdvancedWebView.Browsers.openUrl(this, url) AdvancedWebView.Browsers.openUrl(this, url)
} }
override fun onFileSelection(p0: FileChooserDialog, file: File) {
TelegraphApi.uploadImage(file) { success, src, error ->
if (success && src != null && src.isNotBlank())
editor?.addImage(src)
else showError(error)
}
}
override fun onFileChooserDismissed(p0: FileChooserDialog) {
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
webView?.onResume() webView?.onResume()
@ -176,6 +155,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
webView?.onActivityResult(requestCode, resultCode, data) webView?.onActivityResult(requestCode, resultCode, data)
editor?.onActivityResult(requestCode, resultCode, data)
} }
override fun onBackPressed() { override fun onBackPressed() {
@ -202,10 +182,6 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.image -> {
uploadImage()
true
}
R.id.create -> { R.id.create -> {
loadEditor() loadEditor()
true true
@ -310,9 +286,4 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener, FileChooserD
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
} }

View File

@ -2,14 +2,14 @@ package telegra.ph
import com.github.kittinunf.fuel.android.core.Json import com.github.kittinunf.fuel.android.core.Json
import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel.android.extension.responseJson
import com.github.kittinunf.fuel.core.* import com.github.kittinunf.fuel.core.FuelError
import com.github.kittinunf.fuel.core.FuelManager
import com.github.kittinunf.fuel.core.Request
import com.github.kittinunf.fuel.core.Response
import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.fuel.httpPost
import com.github.kittinunf.fuel.httpUpload
import com.github.kittinunf.result.Result import com.github.kittinunf.result.Result
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.io.File
import java.net.URLConnection
object TelegraphApi { object TelegraphApi {
@ -151,25 +151,4 @@ object TelegraphApi {
} }
} }
fun uploadImage(file: File, callback: (success: Boolean, src: String?, error: String?) -> Unit) {
"http://telegra.ph/upload".httpUpload()
.dataParts { _, _ ->
listOf(DataPart(file, name = "FileUpload", type = URLConnection.guessContentTypeFromName(file.name)))
}
.responseJson { _, _, result ->
val (json, error) = result
if (error == null && json != null) {
val jsonObj = json.array().optJSONObject(0)
val src = jsonObj?.optString("src")
if (src != null) {
callback(true, src, null)
} else {
callback(false, null, null)
}
} else {
callback(false, null, error?.message)
}
}
}
} }

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/image"
android:title="@string/add_image"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/create" android:id="@+id/create"
android:title="@string/create" android:title="@string/create"

View File

@ -25,5 +25,4 @@
<string name="published">Published posts</string> <string name="published">Published posts</string>
<string name="name_question">Your name?</string> <string name="name_question">Your name?</string>
<string name="name_hint">Awesome Writer</string> <string name="name_hint">Awesome Writer</string>
<string name="add_image">Add image</string>
</resources> </resources>