Files
assistant-android/app/src/main/java/com/gh/base/BaseRichEditorActivity.kt

706 lines
29 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.gh.base
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.webkit.JavascriptInterface
import android.widget.CheckBox
import android.widget.FrameLayout
import android.widget.TextView
import androidx.lifecycle.Observer
import butterknife.OnClick
import com.gh.common.AppExecutor
import com.gh.common.runOnIoThread
import com.gh.common.util.*
import com.gh.common.view.RichEditor
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.VideoEntity
import com.gh.gamecenter.qa.editor.GameActivity
import com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity
import com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity
import com.gh.gamecenter.qa.editor.LocalMediaActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.qa.entity.EditorInsertEntity
import com.gh.gamecenter.video.poster.PosterEditActivity
import com.gh.gamecenter.video.upload.UploadManager
import com.google.gson.JsonObject
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_Keyboard
import com.lightgame.utils.Utils
import com.lightgame.view.CheckableImageView
import io.reactivex.disposables.Disposable
import kotterknife.bindView
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarActivity(),
KeyboardHeightObserver, UploadVideoListener {
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)
private val mEditorTextNumTv by bindView<TextView>(R.id.editorTextNumTv)
private val mEditorFont by bindView<CheckableImageView>(R.id.editor_font)
private val mEditorLink by bindView<CheckableImageView>(R.id.editor_link)
private val mEditorFontBold by bindView<CheckableImageView>(R.id.editor_font_bold)
private val mEditorFontItalic by bindView<CheckableImageView>(R.id.editor_font_italic)
private val mEditorFontStrikeThrough by bindView<CheckableImageView>(R.id.editor_font_strikethrough)
private val mEditorFontUnderline by bindView<CheckableImageView>(R.id.editor_font_underline)
private val mEditorParagraphH1 by bindView<CheckableImageView>(R.id.editor_paragraph_h1)
private val mEditorParagraphH2 by bindView<CheckableImageView>(R.id.editor_paragraph_h2)
private val mEditorParagraphH3 by bindView<CheckableImageView>(R.id.editor_paragraph_h3)
private val mEditorParagraphH4 by bindView<CheckableImageView>(R.id.editor_paragraph_h4)
private val mEditorParagraphQuote by bindView<CheckableImageView>(R.id.editor_paragraph_quote)
private val mEditorFontContainer by bindView<View>(R.id.editor_font_container)
private val mEditorParagraphContainer by bindView<View>(R.id.editor_paragraph_container)
private val mEditorLinkContainer by bindView<View>(R.id.editor_link_container)
private val mEditorInsertDetailContainer by bindView<View>(R.id.editor_insert_detail_container)
private val mTagsContainer by bindView<FrameLayout>(R.id.tagsContainer)
private val mUploadVideoGuideContainer by bindView<View>(R.id.uploadVideoGuideContainer)
protected val mOriginalCb by bindView<CheckBox>(R.id.originalCb)
private val mOriginalTipsContainer by bindView<View>(R.id.originalTipsContainer)
private val mOriginalTipsClose by bindView<TextView>(R.id.originalTipsClose)
private var mCurrentParagraphStyle = ""
private var mIsExtendedKeyboardShow = false
private var mAgreePostPic: Boolean = false
private var mGuideDisposable: Disposable? = null
protected lateinit var mViewModel: VM
protected var mIsKeyBoardShow = false
private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
private var mMaxUploadVideoGuideCount = 2
val FILE_HOST = "file:///"
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
DialogUtils.fixWebViewKeyboardNotWorking(this)
if (resultCode != Activity.RESULT_OK) return
val insertData: EditorInsertEntity?
when (requestCode) {
INSERT_ANSWER_CODE -> {
val answer =
data?.getParcelableExtra<AnswerEntity>(AnswerEntity::class.java.simpleName)
if (answer != null) {
mRichEditor.focusEditor()
insertData = EditorInsertEntity.transform(answer)
mRichEditor.insertCustomStyleLink(insertData)
}
}
INSERT_ARTICLE_CODE -> {
val article =
data?.getParcelableExtra<ArticleEntity>(ArticleEntity::class.java.simpleName)
if (article != null) {
mRichEditor.focusEditor()
insertData = EditorInsertEntity.transform(article)
mRichEditor.insertCustomStyleLink(insertData)
}
}
INSERT_GAME_CODE -> {
val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
if (game != null) {
mRichEditor.focusEditor()
insertData = EditorInsertEntity.transform(game)
mRichEditor.insertCustomStyleLink(insertData)
}
}
REQUEST_CODE_IMAGE -> {
if (data != null) mViewModel.uploadPic(data)
}
INSERT_VIDEO_CODE -> {
val localVideoList =
data?.getParcelableArrayListExtra<LocalVideoEntity>(LocalVideoEntity::class.java.name)
?: arrayListOf()
if (localVideoList.isNotEmpty()) {
mRichEditor.focusEditor()
uploadVideo(localVideoList)
}
}
REQUEST_CODE_IMAGE_CROP -> {
val imagePath = data?.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
if (!imagePath.isNullOrEmpty()) {
mViewModel.uploadPoster(imagePath)
}
}
}
closeExtendedKeyboard()
AppExecutor.uiExecutor.executeWithDelay(Runnable {
Util_System_Keyboard.showSoftKeyboard(this)
}, 100)
}
private fun uploadVideo(localVideoList: ArrayList<LocalVideoEntity>) {
mViewModel.localVideoList.addAll(localVideoList)
runOnIoThread {
localVideoList.forEach {
if (it.poster.startsWith("http")) {
runOnUiThread {
mRichEditor.focusEditor()
mRichEditor.insertPlaceholderVideo(it.id, it.poster)
}
} else {
val videoThumbnail = BitmapUtils.getVideoThumbnail(it.filePath)
val filePath = "${cacheDir.absolutePath}${File.separator}${it.id}.webp"
BitmapUtils.saveBitmap(videoThumbnail, filePath)
it.poster = filePath
runOnUiThread {
mRichEditor.focusEditor()
mRichEditor.insertPlaceholderVideo(it.id, "$FILE_HOST${it.poster}")
}
}
}
mViewModel.uploadVideo()
}
}
@SuppressLint("AddJavascriptInterface", "ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel = provideViewModel()
mViewModel.setUploadVideoListener(this)
mKeyboardHeightProvider = KeyboardHeightProvider(this)
mRichEditor.post { mKeyboardHeightProvider?.start() }
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
mRichEditor.addJavascriptInterface(OnCursorChangeListener(), "OnCursorChangeListener")
mRichEditor.addJavascriptInterface(
OnEditorTextChangeListener(),
"OnEditorTextChangeListener"
)
mRichEditor.addJavascriptInterface(OnVideoListener(), "onVideoListener")
mRichEditor.addJavascriptInterface(
OnQuoteCountChangeListener(),
"OnQuoteCountChangeListener"
)
mRichEditor.setInputEnabled(true)
mRichEditor.setPadding(16, 12, 16, 12)
mRichEditor.setOnTouchListener { _, _ ->
if (mIsExtendedKeyboardShow) {
closeExtendedKeyboard()
Util_System_Keyboard.showSoftKeyboard(this)
//是否消费事件根据mRichEditor是否含有焦点决定mRichEditor没有焦点则不消费事件
mRichEditor.hasFocus()
} else false
}
mOriginalCb.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
mOriginalTipsContainer.alpha = 0f
mOriginalTipsContainer.visibility = View.VISIBLE
ObjectAnimator.ofFloat(mOriginalTipsContainer, "alpha", 0f, 1f).setDuration(200).start()
}
}
observeData()
}
private fun observeData() {
mViewModel.chooseImagesUpload.observe(this, Observer {
mRichEditor.focusEditor()
for (key in it.keys) {
mRichEditor.insertPlaceholderImage(key)
}
})
mViewModel.chooseImagesUploadSuccess.observe(this, Observer {
val jsonArray = JSONArray()
for (key in it.keys) {
val jsonObject = JSONObject()
jsonObject.put("id", key)
jsonObject.put("url", it[key])
jsonArray.put(jsonObject)
}
mRichEditor.replacePlaceholderImage(jsonArray.toString())
})
}
override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
mIsKeyBoardShow = height > 0
if (height > 0) {
closeExtendedKeyboard()
}
}
fun closeExtendedKeyboard() {
mEditorInsertDetailContainer.visibility = View.GONE
mEditorFont.isChecked = false
mEditorLink.isChecked = false
mIsExtendedKeyboardShow = false
}
protected fun controlEditorInsertContainerEnabled(isEnabled: Boolean) {
mEditorFont.isEnabled = isEnabled
}
@OnClick(
R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_font_underline,
R.id.editor_font_bold, R.id.editor_font_italic, R.id.editor_font_strikethrough,
R.id.editor_paragraph_h1, R.id.editor_paragraph_h2, R.id.editor_paragraph_h3,
R.id.editor_paragraph_h4, R.id.editor_font_container, R.id.editor_paragraph_container,
R.id.editor_paragraph_quote, R.id.editor_link_answer, R.id.editor_link_article,
R.id.editor_link_game, R.id.editor_link_video, R.id.uploadVideoGuideClose,
R.id.originalTipsClose
)
fun onRichClick(view: View) {
when (view.id) {
R.id.editor_font -> {
controlEditorFontContainer()
}
R.id.editor_link -> {
controlEditorLinkContainer()
}
R.id.editor_font_bold -> {
mEditorFontBold.isChecked = !mEditorFontBold.isChecked
mRichEditor.setBold()
if (mEditorFontBold.isChecked) {
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-加粗")
}
}
R.id.editor_font_italic -> {
mEditorFontItalic.isChecked = !mEditorFontItalic.isChecked
mRichEditor.setItalic()
if (mEditorFontItalic.isChecked) {
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-斜体")
}
}
R.id.editor_font_strikethrough -> {
mEditorFontStrikeThrough.isChecked = !mEditorFontStrikeThrough.isChecked
mRichEditor.setStrikeThrough()
if (mEditorFontStrikeThrough.isChecked) {
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-删除线")
}
}
R.id.editor_font_underline -> {
mEditorFontUnderline.isChecked = !mEditorFontUnderline.isChecked
mRichEditor.setUnderline()
if (mEditorFontUnderline.isChecked) {
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-下滑线")
}
}
R.id.editor_paragraph_h1 -> {
if (mEditorParagraphH1.isChecked) {
mRichEditor.formatBlock()
} else {
MtaHelper.onEvent(mtaEventName(), "段落样式", "段落样式-1级标题")
mRichEditor.setHeading(1)
}
mEditorParagraphH1.isChecked = !mEditorParagraphH1.isChecked
}
R.id.editor_paragraph_h2 -> {
if (mEditorParagraphH2.isChecked) {
mRichEditor.formatBlock()
} else {
MtaHelper.onEvent(mtaEventName(), "段落样式", "段落样式-2级标题")
mRichEditor.setHeading(2)
}
mEditorParagraphH2.isChecked = !mEditorParagraphH2.isChecked
}
R.id.editor_paragraph_h3 -> {
if (mEditorParagraphH3.isChecked) {
mRichEditor.formatBlock()
} else {
MtaHelper.onEvent(mtaEventName(), "段落样式", "段落样式-3级标题")
mRichEditor.setHeading(3)
}
mEditorParagraphH3.isChecked = !mEditorParagraphH3.isChecked
}
R.id.editor_paragraph_h4 -> {
if (mEditorParagraphH4.isChecked) {
mRichEditor.formatBlock()
} else {
MtaHelper.onEvent(mtaEventName(), "段落样式", "段落样式-4级标题")
mRichEditor.setHeading(4)
}
mEditorParagraphH4.isChecked = !mEditorParagraphH4.isChecked
}
R.id.editor_paragraph_quote -> {
if (mEditorParagraphQuote.isChecked) {
mRichEditor.formatBlock()
} else {
MtaHelper.onEvent(mtaEventName(), "段落样式", "段落样式-引用")
mRichEditor.setBlockquote()
}
mEditorParagraphQuote.isChecked = !mEditorParagraphQuote.isChecked
}
R.id.editor_link_answer -> {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-回答")
startActivityForResult(
InsertAnswerWrapperActivity.getIntent(this),
INSERT_ANSWER_CODE
)
}
R.id.editor_link_article -> {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-文章")
startActivityForResult(
InsertArticleWrapperActivity.getIntent(this),
INSERT_ARTICLE_CODE
)
}
R.id.editor_link_game -> {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-游戏")
startActivityForResult(
GameActivity.getIntent(this, GameActivity.INSERT_GAME_TITLE),
INSERT_GAME_CODE
)
}
R.id.editor_link_video -> {
PermissionHelper.checkStoragePermissionBeforeAction(this,
object : EmptyCallback {
override fun onCallback() {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")
startActivityForResult(
LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.VIDEO,
3,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
), INSERT_VIDEO_CODE
)
NewLogUtils.logChooseMedia(
"view_media",
if (mtaEventName() == "提问帖") "提问帖" else "帖子",
"视频"
)
}
})
}
R.id.editor_image -> {
if (!mAgreePostPic && !NetworkUtils.isWifiOr4GOr3GConnected(this)) {
mAgreePostPic = true
DialogHelper.showDialog(
this,
"警告",
"当前使用移动网络,上传图片会消耗手机流量",
"我知道了", "", { startMediaStore() },
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
return
}
startMediaStore()
NewLogUtils.logChooseMedia(
"view_media",
if (mtaEventName() == "提问帖") "提问帖" else "帖子",
"图片"
)
}
R.id.uploadVideoGuideClose -> {
hideUploadVideoGuide()
if (mGuideDisposable != null && !mGuideDisposable!!.isDisposed) {
mGuideDisposable!!.dispose()
mGuideDisposable = null
}
}
R.id.originalTipsClose -> {
val animator = ObjectAnimator.ofFloat(mOriginalTipsContainer, "alpha", 1f, 0f).setDuration(200)
animator.doOnEnd {
mOriginalTipsContainer.visibility = View.GONE
}
animator.start()
}
}
}
private fun startMediaStore() {
MtaHelper.onEvent(mtaEventName(), "插入图片", "插入图片")
if (mViewModel.mapImages.size >= 50) {
toast(R.string.answer_edit_max_img_hint)
return
}
try {
PermissionHelper.checkStoragePermissionBeforeAction(this, object : EmptyCallback {
override fun onCallback() {
val intent = LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.IMAGE,
10,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
)
startActivityForResult(intent, REQUEST_CODE_IMAGE)
}
})
} catch (e: Exception) {
toast(R.string.media_image_hint)
e.printStackTrace()
}
}
private fun controlEditorFontContainer() {
mEditorFont.isChecked = !mEditorFont.isChecked
mEditorLink.isChecked = false
val isShouldDelay = if (mEditorFont.isChecked) {
Util_System_Keyboard.hideSoftKeyboard(this)
true
} else {
Util_System_Keyboard.showSoftKeyboard(this)
false
}
mEditorInsertDetailContainer.postDelayed({
mEditorInsertDetailContainer.visibility =
if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorFontContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorParagraphContainer.visibility =
if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorFont.isChecked
}, if (isShouldDelay) 200 else 0L)
}
private fun controlEditorLinkContainer() {
mEditorLink.isChecked = !mEditorLink.isChecked
mEditorFont.isChecked = false
val isShouldDelay = if (mEditorLink.isChecked) {
Util_System_Keyboard.hideSoftKeyboard(this)
true
} else {
Util_System_Keyboard.showSoftKeyboard(this)
false
}
mEditorInsertDetailContainer.postDelayed({
mEditorInsertDetailContainer.visibility =
if (mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorFontContainer.visibility = View.GONE
mEditorParagraphContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorLink.isChecked
}, if (isShouldDelay) 200 else 0L)
}
override fun handleBackPressed(): Boolean {
if (mIsExtendedKeyboardShow) {
closeExtendedKeyboard()
return true
}
return super.handleBackPressed()
}
override fun onResume() {
super.onResume()
mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
}
override fun onPause() {
super.onPause()
mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
}
//视频上传功能引导
fun showUploadVideoGuide() {
mUploadVideoGuideContainer.postDelayed({
val count = SPUtils.getInt(getVideoGuideKey(), 0)
if (count >= mMaxUploadVideoGuideCount) return@postDelayed
mUploadVideoGuideContainer.alpha = 0f
mUploadVideoGuideContainer.visibility = View.VISIBLE
mUploadVideoGuideContainer.animate().alpha(1f).setDuration(200).start()
mGuideDisposable = countDownTimer(3) { finish, _ ->
if (finish) {
hideUploadVideoGuide()
}
}
SPUtils.setInt(getVideoGuideKey(), count + 1)
}, 1000)
}
fun hideUploadVideoGuide() {
val animate = mUploadVideoGuideContainer.animate().alpha(0f).setDuration(200)
animate.doOnEnd {
mUploadVideoGuideContainer.visibility = View.GONE
}
animate.start()
}
override fun onDestroy() {
super.onDestroy()
mKeyboardHeightProvider?.close()
val path = mViewModel.currentUploadingVideo?.filePath
if (path != null && UploadManager.isUploading(path)) {
UploadManager.cancelTask(path)
}
if (mGuideDisposable != null && !mGuideDisposable!!.isDisposed) {
mGuideDisposable!!.dispose()
mGuideDisposable = null
}
}
private inner class OnCursorChangeListener {
@JavascriptInterface
fun onElements(elements: String) {
Utils.log("-----------------------")
Utils.log(elements)
Utils.log(mRichEditor.html)
Utils.log("-----------------------")
mCurrentParagraphStyle = when {
elements.contains(ELEMENT_PARAGRAPH_QUOTE) -> ELEMENT_PARAGRAPH_QUOTE
elements.contains(ELEMENT_PARAGRAPH_P) -> ELEMENT_PARAGRAPH_P
else -> ""
}
mBaseHandler.post {
mEditorFontBold.isChecked = elements.contains(ELEMENT_NAME_BOLD)
mEditorFontItalic.isChecked = elements.contains(ELEMENT_NAME_ITALIC)
mEditorFontStrikeThrough.isChecked = elements.contains(ELEMENT_NAME_STRIKE)
mEditorFontUnderline.isChecked = elements.contains(ELEMENT_NAME_UNDERLINE)
mEditorParagraphH1.isChecked = elements.contains(ELEMENT_PARAGRAPH_H1)
mEditorParagraphH2.isChecked = elements.contains(ELEMENT_PARAGRAPH_H2)
mEditorParagraphH3.isChecked = elements.contains(ELEMENT_PARAGRAPH_H3)
mEditorParagraphH4.isChecked = elements.contains(ELEMENT_PARAGRAPH_H4)
mEditorParagraphQuote.isChecked = elements.contains(ELEMENT_PARAGRAPH_QUOTE)
}
}
}
private inner class OnPasteListener {
@JavascriptInterface
fun onPaste() {
val clipboard =
HaloApp.getInstance().application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipText = clipboard.text.toString()
if (!TextUtils.isEmpty(clipText)) {
// 替换换行符号否则 插入失败
val text = clipText.replace("[ ]".toRegex(), "&nbsp;")
.replace("[\r\n]".toRegex(), "<br/>")
mBaseHandler.post { mRichEditor.insertHtml(text) }
}
}
}
private inner class OnEditorTextChangeListener {
@JavascriptInterface
fun onTextChange(count: Int) {
val num = if (count > MAX_INPUT_TEXT_NUM) MAX_INPUT_TEXT_NUM - count else count
mEditorTextNumTv.post {
mEditorTextNumTv.text = num.toString()
mViewModel.quoteCountEntity.textCount = num
}
}
}
private inner class OnQuoteCountChangeListener {
@JavascriptInterface
fun onQuoteCountChange(
imageCount: Int,
articleCount: Int,
answerCount: Int,
videoCount: Int,
gameCount: Int
) {
mEditorTextNumTv.post {
mViewModel.quoteCountEntity.apply {
this.imageCount = imageCount
this.articleCount = articleCount
this.answerCount = answerCount
this.videoCount = videoCount
this.gameCount = gameCount
}
}
}
}
private inner class OnVideoListener {
@JavascriptInterface
fun showDeleteDialog(id: String) {
DialogHelper.showDialog(this@BaseRichEditorActivity, "提示", "确定删除吗?", "确定", "取消", {
runOnUiThread {
mRichEditor.delPlaceholderVideo(id)
mViewModel.deleteVideo(id)
}
})
}
@JavascriptInterface
fun updatePoster(id: String, videoId: String, url: String) {
mViewModel.id = id
mViewModel.videoId = videoId
val videoEntity = VideoEntity(url = url)
val intent =
PosterEditActivity.getIntentByVideo(this@BaseRichEditorActivity, videoEntity)
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
}
@JavascriptInterface
fun deleteUploadingVideo(id: String) {
mViewModel.deleteVideo(id)
}
@JavascriptInterface
fun reUploadVideo(id: String) {
val video = mViewModel.uploadVideoErrorList.find { it.id == id }
if (video != null) {
mViewModel.localVideoList.add(video)
mViewModel.uploadVideoErrorList.remove(video)
mViewModel.uploadVideo()
}
}
}
override fun insertPlaceholderVideo(id: String, poster: String) {
mRichEditor.insertPlaceholderVideo(id, poster)
}
override fun updateVideoProgress(id: String, progress: String) {
mRichEditor.updateVideoProgress(id, progress)
}
override fun videoUploadFinished(id: String, url: String, msg: JsonObject) {
try {
val obj = JSONObject()
obj.put("poster", msg.get("poster").asString)
obj.put("url", msg.get("url").asString)
obj.put("duration", RichEditor.formatVideoDuration(msg.get("length").asLong))
obj.put("id", msg.get("_id").asString)
obj.put("status", "pending")
mRichEditor.videoUploadFinished(id, url, obj.toString())
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
override fun changePoster(id: String, poster: String) {
mRichEditor.changePoster(id, poster)
}
override fun videoUploadFailed(id: String) {
mRichEditor.videoUploadFailed(id)
}
open fun getSelectedLabel(): Int = 0
open fun onActivityDialogResult(requestCode: Int, resultCode: Int, data: Intent?) {}
abstract fun mtaEventName(): String
abstract fun provideViewModel(): VM
abstract fun getVideoGuideKey(): String
companion object {
const val ELEMENT_NAME_BOLD = " b "
const val ELEMENT_NAME_ITALIC = " i "
const val ELEMENT_NAME_STRIKE = " strike "
const val ELEMENT_NAME_UNDERLINE = " u "
const val ELEMENT_PARAGRAPH_H1 = " h1 "
const val ELEMENT_PARAGRAPH_H2 = " h2 "
const val ELEMENT_PARAGRAPH_H3 = " h3 "
const val ELEMENT_PARAGRAPH_H4 = " h4 "
const val ELEMENT_PARAGRAPH_P = " p "
const val ELEMENT_PARAGRAPH_QUOTE = " blockquote "
const val INSERT_ANSWER_CODE = 411
const val INSERT_ARTICLE_CODE = 412
const val INSERT_GAME_CODE = 413
const val MAX_INPUT_TEXT_NUM = 10000
const val REQUEST_CODE_IMAGE = 120
const val INSERT_VIDEO_CODE = 121
const val REQUEST_CODE_IMAGE_CROP = 122
}
}