增加问题草稿功能
This commit is contained in:
@ -118,7 +118,7 @@ class SimulatorDownloadManager private constructor() {
|
||||
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
|
||||
logShowEvent = true
|
||||
)
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, Gravity.LEFT, {
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, Gravity.LEFT, false, {
|
||||
if (shouldShowUpdate && isInstalled) {
|
||||
cancelCallback?.invoke()
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
|
||||
|
||||
@ -350,7 +350,7 @@ public class DialogUtils {
|
||||
* @param cmListener 确认按钮监听
|
||||
*/
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, TrackableEntity trackableEntity, int gravity, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
, String negative, String positive, TrackableEntity trackableEntity, int gravity, boolean shouldShowCloseBtn, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
final Dialog dialog;
|
||||
if (trackableEntity != null) {
|
||||
@ -373,6 +373,7 @@ public class DialogUtils {
|
||||
TextView cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
TextView confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
View middleLine = contentView.findViewById(R.id.middle_line);
|
||||
View closeIv = contentView.findViewById(R.id.closeIv);
|
||||
titleTv.setGravity(gravity);
|
||||
contentTv.setGravity(gravity);
|
||||
|
||||
@ -389,6 +390,8 @@ public class DialogUtils {
|
||||
confirmBtn.setVisibility(View.GONE);
|
||||
middleLine.setVisibility(View.GONE);
|
||||
}
|
||||
closeIv.setVisibility(shouldShowCloseBtn ? View.VISIBLE : View.GONE);
|
||||
closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
if (clListener != null) clListener.onCancel();
|
||||
@ -413,7 +416,12 @@ public class DialogUtils {
|
||||
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, Gravity.LEFT, clListener, cmListener);
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, Gravity.LEFT, false, clListener, cmListener);
|
||||
}
|
||||
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, int gravity, boolean shouldShowCloseBtn, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, gravity, shouldShowCloseBtn, clListener, cmListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1951,8 +1959,8 @@ public class DialogUtils {
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_energy, null);
|
||||
((TextView)contentView.findViewById(R.id.userName)).setText("\"" + userName + "\"");
|
||||
((TextView)contentView.findViewById(R.id.energy)).setText(energy + "");
|
||||
((TextView) contentView.findViewById(R.id.userName)).setText("\"" + userName + "\"");
|
||||
((TextView) contentView.findViewById(R.id.energy)).setText(energy + "");
|
||||
|
||||
contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
|
||||
@ -24,6 +24,7 @@ import com.gh.common.util.HtmlUtils;
|
||||
import com.gh.common.util.ImageUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.NetworkUtils;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.RichEditorUtils;
|
||||
import com.gh.common.util.SPUtils;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
@ -662,6 +663,16 @@ public class RichEditor extends WebView {
|
||||
return DeviceUtils.getNetwork(HaloApp.getInstance().getApplication());
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public String getAppVersion() {
|
||||
return BuildConfig.VERSION_NAME;
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public int getAppVersionCode() {
|
||||
return PackageUtils.getVersionCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示toast
|
||||
*
|
||||
|
||||
@ -69,7 +69,7 @@ class ForumMyFollowAdapter(context: Context, val mViewModel: ForumMyFollowViewMo
|
||||
popupWindow.dismiss()
|
||||
when (text) {
|
||||
"取消关注" -> {
|
||||
DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, {}, {
|
||||
DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, false, {}, {
|
||||
MtaHelper.onEvent("论坛首页", "我关注的论坛", "取消关注")
|
||||
mViewModel.unFollowForum(entity.id) {
|
||||
EventBus.getDefault().post(EBForumFollowChange(entity, false))
|
||||
|
||||
@ -54,7 +54,7 @@ class ForumAdapter(val context: Context, val mViewModel: ForumSelectViewModel?,
|
||||
mContext.ifLogin("论坛-选择论坛") {
|
||||
debounceActionWithInterval(it.id) {
|
||||
if (forumEntity.isFollow) {
|
||||
DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, {}, {
|
||||
DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, false, {}, {
|
||||
mViewModel?.unFollowForum(forumEntity.id) {
|
||||
MtaHelper.onEvent("论坛首页", "选择论坛", "关注")
|
||||
forumEntity.isFollow = false
|
||||
|
||||
@ -31,8 +31,6 @@ import com.gh.gamecenter.qa.entity.Questions
|
||||
import com.gh.gamecenter.video.VideoVerifyItemViewHolder
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.MimeType
|
||||
import org.json.JSONArray
|
||||
@ -44,6 +42,7 @@ import org.json.JSONObject
|
||||
class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
|
||||
private lateinit var mMenuDraft: MenuItem
|
||||
private lateinit var mMenuPost: MenuItem
|
||||
private lateinit var mBinding: FragmentAnswerEditBinding
|
||||
private lateinit var mViewModel: AnswerEditViewModel
|
||||
|
||||
@ -84,6 +83,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
super.onCreate(savedInstanceState)
|
||||
setToolbarMenu(R.menu.menu_answer_post)
|
||||
mMenuDraft = mToolbar.menu.findItem(R.id.menu_draft)
|
||||
mMenuPost = mToolbar.menu.findItem(R.id.menu_answer_post)
|
||||
mCommunityName = intent?.getStringExtra(EntranceUtils.KEY_COMMUNITY_NAME)
|
||||
mOpenAnswerInNewPage = intent?.getBooleanExtra(EntranceUtils.KEY_ANSWER_OPEN_IN_NEW_PAGE, false)!!
|
||||
mBinding = FragmentAnswerEditBinding.bind(mContentView)
|
||||
@ -108,6 +108,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mBinding.answerPlaceholder.visibility = if (t.contains("<img src") || !TextUtils.isEmpty(mRichEditor.text)) {
|
||||
View.GONE
|
||||
} else View.VISIBLE
|
||||
checkPostButtonEnable()
|
||||
}
|
||||
|
||||
mRichEditor.setOnInitialLoadListener { isReady ->
|
||||
@ -134,6 +135,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
|
||||
mKeyboardHeightProvider = KeyboardHeightProvider(this)
|
||||
mBinding.root.post { mKeyboardHeightProvider?.start() }
|
||||
checkPostButtonEnable()
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
@ -277,6 +279,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mViewModel.draftsLiveData.observe(this, Observer {
|
||||
mRichEditor.setHtml(it, false)
|
||||
requestFocusAndMoveCursorToEnd()
|
||||
checkPostButtonEnable()
|
||||
})
|
||||
|
||||
mViewModel.saveDraftsLiveData.observeNonNull(this) {
|
||||
@ -375,23 +378,32 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
val answerContent = getReplaceRealContent()
|
||||
mRichEditor.showLinkStyle()
|
||||
if (mRichEditor.hasPlaceholderImage()) {
|
||||
ToastUtils.showToast("图片正在上传中")
|
||||
ToastUtils.showToast("图片上传ing")
|
||||
return@postDelayed
|
||||
}
|
||||
// filter rule
|
||||
val answerLength = HtmlUtils.stripHtml(answerContent).length
|
||||
if (answerLength < MIN_ANSWER_TEXT_LENGTH) {
|
||||
ToastUtils.showToast(getString(R.string.answer_beneath_length_limit), if (mIsKeyBoardShow) Gravity.CENTER else -1)
|
||||
return@postDelayed
|
||||
} else if (answerLength > MAX_ANSWER_TEXT_LENGTH) {
|
||||
ToastUtils.showToast("回答最多输入10000个字", if (mIsKeyBoardShow) Gravity.CENTER else -1)
|
||||
return@postDelayed
|
||||
if (checkData(answerContent)) {
|
||||
mViewModel.postAnswer(answerContent)
|
||||
}
|
||||
mViewModel.postAnswer(answerContent)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkData(answerContent: String, isShowToast: Boolean = true): Boolean {
|
||||
val answerLength = HtmlUtils.stripHtml(answerContent).length
|
||||
if (answerLength < MIN_ANSWER_TEXT_LENGTH) {
|
||||
if (isShowToast) ToastUtils.showToast(getString(R.string.answer_beneath_length_limit), if (mIsKeyBoardShow) Gravity.CENTER else -1)
|
||||
return false
|
||||
} else if (answerLength > MAX_ANSWER_TEXT_LENGTH) {
|
||||
if (isShowToast) ToastUtils.showToast("回答最多输入10000个字", if (mIsKeyBoardShow) Gravity.CENTER else -1)
|
||||
return false
|
||||
}
|
||||
val draftValue = mViewModel.draftsLiveData.value
|
||||
if (!draftValue.isNullOrEmpty()) {
|
||||
return draftValue != answerContent
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getReplaceRealContent(): String {
|
||||
var answerContent = mRichEditor.html
|
||||
for (s in mViewModel.mapImages.keys) {
|
||||
@ -403,6 +415,12 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
return answerContent
|
||||
}
|
||||
|
||||
private fun checkPostButtonEnable() {
|
||||
val answerContent = getReplaceRealContent()
|
||||
val isEnabled = checkData(answerContent, false)
|
||||
mMenuPost.actionView.alpha = if (isEnabled) 1f else 0.6f
|
||||
}
|
||||
|
||||
override fun handleBackPressed(): Boolean {
|
||||
return if (TextUtils.isEmpty(UserManager.getInstance().token)) {
|
||||
false
|
||||
@ -417,14 +435,9 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
&& !mRichEditor.html.contains("<img src")
|
||||
&& TextUtils.isEmpty(mRichEditor.text)) {
|
||||
consume {
|
||||
DialogUtils.showAlertDialog(
|
||||
this,
|
||||
"提示",
|
||||
"当前内容为空,退出即会删除该草稿,确定退出吗?",
|
||||
"确定",
|
||||
"取消",
|
||||
{ mViewModel.deleteAnswerDraft() },
|
||||
null)
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "当前内容为空,退出即会删除该草稿,确定退出吗?", "取消", "确定", null, {
|
||||
mViewModel.deleteAnswerDraft()
|
||||
})
|
||||
}
|
||||
} else if (!TextUtils.isEmpty(mViewModel.cacheAnswerContent)
|
||||
&& mViewModel.cacheAnswerContent == mRichEditor.html) {
|
||||
@ -443,21 +456,17 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
}
|
||||
|
||||
private fun showDraftFailureDialog() {
|
||||
DialogUtils.showAlertDialog(this,
|
||||
"提示",
|
||||
"确定退出?已撰写的内容将会丢失",
|
||||
"继续撰写", "退出", null, { finish() })
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "确定退出?已撰写的内容将会丢失?", "退出", "继续撰写", {
|
||||
finish()
|
||||
}, null)
|
||||
}
|
||||
|
||||
private fun showPatchBackDialog() {
|
||||
DialogUtils.showCancelAlertDialog(this,
|
||||
"提示",
|
||||
"即将退出修改,是否需要将此次编辑保存到草稿箱?",
|
||||
"保存草稿",
|
||||
"继续退出",
|
||||
{
|
||||
saveDraft(true)
|
||||
}, { finish() })
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "是否保存修改内容用于下次编辑?", "不保存", "保存并退出", {
|
||||
finish()
|
||||
}, {
|
||||
saveDraft(true)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -492,8 +492,10 @@ class ArticleDetailFragment : BaseArticleDetailCommentFragment<CommentItemData,
|
||||
mViewModel.detailEntity?.me?.isCommunityArticleVote = alreadyLiked
|
||||
if (alreadyLiked) {
|
||||
bottomLikeIv.setImageResource(R.drawable.ic_article_detail_liked)
|
||||
bottomLikeTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font))
|
||||
} else {
|
||||
bottomLikeIv.setImageResource(R.drawable.ic_article_detail_like_bottom_bar)
|
||||
bottomLikeTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_666666))
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,9 +503,11 @@ class ArticleDetailFragment : BaseArticleDetailCommentFragment<CommentItemData,
|
||||
if (isCollected) {
|
||||
bottomStarTv.text = "已收藏"
|
||||
bottomStarIv.setImageResource(R.drawable.ic_article_detail_stared)
|
||||
bottomStarTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font))
|
||||
} else {
|
||||
bottomStarTv.text = "收藏"
|
||||
bottomStarIv.setImageResource(R.drawable.ic_article_detail_star)
|
||||
bottomStarTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_666666))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -398,12 +398,12 @@ abstract class BaseArticleDetailCommentAdapter(context: Context,
|
||||
})
|
||||
}
|
||||
"置顶" -> {
|
||||
DialogUtils.showNewAlertDialog(binding.root.context, "提示", "是否将此条评论置顶?", "取消", "确认", null, Gravity.CENTER, {}, {
|
||||
DialogUtils.showNewAlertDialog(binding.root.context, "提示", "是否将此条评论置顶?", "取消", "确认", null, Gravity.CENTER, false, {}, {
|
||||
commentTop(binding.root.context, viewModel, comment, false)
|
||||
})
|
||||
}
|
||||
"取消置顶" -> {
|
||||
DialogUtils.showNewAlertDialog(binding.root.context, "提示", "是否将此条评论取消置顶?", "取消", "确认", null, Gravity.CENTER, {}, {
|
||||
DialogUtils.showNewAlertDialog(binding.root.context, "提示", "是否将此条评论取消置顶?", "取消", "确认", null, Gravity.CENTER, false, {}, {
|
||||
viewModel.updateCommentTop(comment.id
|
||||
?: "", top = false, isAgain = false) { isSuccess, errorCode ->
|
||||
if (isSuccess) {
|
||||
@ -433,7 +433,7 @@ abstract class BaseArticleDetailCommentAdapter(context: Context,
|
||||
viewModel.load(LoadType.REFRESH)
|
||||
} else {
|
||||
if (errorCode == 403095) {
|
||||
DialogUtils.showNewAlertDialog(context, "提示", "当前已有置顶评论,\n是否将此条评论覆盖展示?", "取消", "确认", null, Gravity.CENTER, {}, {
|
||||
DialogUtils.showNewAlertDialog(context, "提示", "当前已有置顶评论,\n是否将此条评论覆盖展示?", "取消", "确认", null, Gravity.CENTER, false, {}, {
|
||||
commentTop(context, viewModel, comment, true)
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,10 +3,13 @@ package com.gh.gamecenter.qa.article.draft
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.common.util.checkStoragePermissionBeforeAction
|
||||
import com.gh.common.view.CustomDividerItemDecoration
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
import com.gh.gamecenter.baselist.LoadType
|
||||
@ -89,6 +92,12 @@ class ArticleDraftFragment : ListFragment<ArticleDraftEntity, NormalListViewMode
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemDecoration(): RecyclerView.ItemDecoration? {
|
||||
val insetDivider = ContextCompat.getDrawable(requireContext(), R.drawable.divider_item_line_space_16)
|
||||
val itemDecoration = CustomDividerItemDecoration(requireContext(), notDecorateTheLastItem = true)
|
||||
itemDecoration.setDrawable(insetDivider!!)
|
||||
return itemDecoration
|
||||
}
|
||||
|
||||
private fun deleteDraft(entity: ArticleDraftEntity) {
|
||||
mApi.deleteArticleDrafts(entity.community.id, entity.id)
|
||||
@ -96,7 +105,15 @@ class ArticleDraftFragment : ListFragment<ArticleDraftEntity, NormalListViewMode
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
mListViewModel.load(LoadType.REFRESH)
|
||||
val index = mAdapter?.entityList?.indexOf(entity) ?: -1
|
||||
if (index >= 0) {
|
||||
mAdapter?.entityList?.remove(entity)
|
||||
if (mAdapter?.entityList.isNullOrEmpty()) {
|
||||
mListViewModel.load(LoadType.REFRESH)
|
||||
} else {
|
||||
mAdapter?.notifyItemRemoved(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
|
||||
@ -9,9 +9,9 @@ import android.os.Bundle
|
||||
import android.os.Message
|
||||
import android.text.InputFilter
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.*
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
@ -138,8 +138,6 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
//setEditTextInputSpace()
|
||||
mEditTitle.filters = arrayOf(TextHelper.getFilter(50, "标题最多50个字"))
|
||||
|
||||
mEditTitle.requestFocus()
|
||||
|
||||
mEditTitle.doOnTextChanged { text, start, count, after ->
|
||||
if (text?.contains("\n") == true) {
|
||||
mEditTitle.setText(text.toString().replace("\n", ""))
|
||||
@ -194,7 +192,7 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
EventBus.getDefault().post(EBReuse(ARTICLE_DRAFT_CHANGE_TAG))
|
||||
finish()
|
||||
} else {
|
||||
showDraftFailureDialog()
|
||||
//showDraftFailureDialog()
|
||||
}
|
||||
}
|
||||
SaveDraftType.AUTO -> {
|
||||
@ -288,6 +286,7 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mGameName.isEnabled = false
|
||||
mGameName.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
}
|
||||
mEditTitle.requestFocus()
|
||||
}
|
||||
mViewModel.notSelectForum.observe(this, Observer {
|
||||
if (it) showSelectGameDialog()
|
||||
@ -361,7 +360,6 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mViewModel.mSelectCommunityData?.icon = mViewModel.draftEntity?.community?.game?.getIcon()
|
||||
mViewModel.mSelectCommunityData?.iconSubscript = mViewModel.draftEntity?.community?.game?.iconSubscript
|
||||
mEditTitle.setText(mViewModel.draftEntity?.title)
|
||||
mMenuDraft.isVisible = false
|
||||
mGameName.isEnabled = true
|
||||
setGameName()
|
||||
mViewModel.getArticleDraftsContent(mViewModel.draftEntity?.id!!)
|
||||
@ -373,7 +371,8 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mViewModel.mSelectCommunityData?.iconSubscript = mViewModel.detailEntity?.community?.game?.iconSubscript
|
||||
setGameName()
|
||||
|
||||
mMenuDraft.isVisible = true
|
||||
//编辑帖子草稿箱入口不存在
|
||||
mMenuDraft.isVisible = false
|
||||
mGameName.isEnabled = false
|
||||
mGameName.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
|
||||
@ -391,9 +390,6 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mRichEditor.setHtml(html, false)
|
||||
try {
|
||||
mRichEditor.scrollTo(0, 10000000)
|
||||
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(mRichEditor, InputMethodManager.SHOW_IMPLICIT)
|
||||
mRichEditor.postDelayed({ mRichEditor.focusEditor() }, 800)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
@ -418,70 +414,57 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
return false
|
||||
}
|
||||
|
||||
if (mViewModel.detailEntity != null) {
|
||||
return if (!TextUtils.isEmpty(mEditTitle.text)
|
||||
|| mRichEditor.html.contains("<img src")
|
||||
|| !TextUtils.isEmpty(mRichEditor.text)) {
|
||||
showPatchBackDialog()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
return !checkDraft(SaveDraftType.EXIT)
|
||||
}
|
||||
|
||||
private fun checkDraft(saveType: SaveDraftType): Boolean {
|
||||
if (mViewModel.detailEntity != null) return true
|
||||
if (mRichEditor.hasPlaceholderImage()) return true
|
||||
|
||||
val draftEntity = mViewModel.draftEntity
|
||||
|
||||
// 内容为空直接弹窗
|
||||
if (saveType == SaveDraftType.EXIT
|
||||
&& TextUtils.isEmpty(mEditTitle.text)
|
||||
&& !mRichEditor.html.contains("<img src")
|
||||
&& TextUtils.isEmpty(mRichEditor.text)
|
||||
&& mViewModel.draftEntity != null) {
|
||||
DialogUtils.showAlertDialog(
|
||||
this,
|
||||
"提示",
|
||||
"当前内容为空,退出即会删除该草稿,确定退出吗?",
|
||||
"确定",
|
||||
"取消",
|
||||
{
|
||||
mViewModel.deleteDraft()
|
||||
finish()
|
||||
},
|
||||
null)
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查草稿内容是否有变动
|
||||
if (draftEntity != null) {
|
||||
if (draftEntity.community.id == mViewModel.mSelectCommunityData?.id &&
|
||||
draftEntity.title == mEditTitle.text.toString() &&
|
||||
mViewModel.articleDraftsContent.value == mRichEditor.html) {
|
||||
//帖子发布,需判断是否输入了内容,输入了则弹窗提示
|
||||
if (mViewModel.detailEntity == null && mViewModel.draftEntity == null) {
|
||||
if (mViewModel.mSelectCommunityData != null
|
||||
&& (mEditTitle.text.toString().isNotEmpty()
|
||||
|| mRichEditor.html.isNotEmpty())) {
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "是否保存内容再退出?", "不保存", "保存并退出", Gravity.CENTER, true, {
|
||||
finish()
|
||||
}, {
|
||||
mViewModel.title = mEditTitle.text.toString()
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mViewModel.postArticleDrafts(SaveDraftType.EXIT)
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (mRichEditor.html.contains("<img src")
|
||||
|| !TextUtils.isEmpty(mRichEditor.text)
|
||||
|| !TextUtils.isEmpty(mEditTitle.text.trim())) {
|
||||
if (mViewModel.mSelectCommunityData == null) {
|
||||
if (saveType == SaveDraftType.EXIT) {
|
||||
showDraftFailureDialog()
|
||||
} else {
|
||||
toast("请选择论坛")
|
||||
}
|
||||
//帖子编辑,需要判断是否修改过
|
||||
if (mViewModel.detailEntity != null) {
|
||||
return if (mViewModel.detailEntity?.community?.id != mViewModel.mSelectCommunityData?.id
|
||||
|| mViewModel.detailEntity?.title != mEditTitle.text.toString()
|
||||
|| mViewModel.detailEntity?.content != mRichEditor.html) {
|
||||
showBackDialog()
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
//检查草稿数据
|
||||
return !checkDraft(SaveDraftType.EXIT)
|
||||
}
|
||||
|
||||
private fun checkDraft(saveType: SaveDraftType): Boolean {
|
||||
val draftEntity = mViewModel.draftEntity ?: return true
|
||||
if (draftEntity.title.isEmpty() && draftEntity.content.isEmpty()) return true
|
||||
if (saveType == SaveDraftType.SKIP) {
|
||||
//判断是否修改了草稿,修改了需自动保存无需提示
|
||||
if (draftEntity.community.id != mViewModel.mSelectCommunityData?.id
|
||||
|| draftEntity.title != mEditTitle.text.toString()
|
||||
|| mViewModel.articleDraftsContent.value != mRichEditor.html) {
|
||||
mViewModel.title = mEditTitle.text.toString()
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mViewModel.postArticleDrafts(SaveDraftType.AUTO)
|
||||
return true
|
||||
}
|
||||
} else if (saveType == SaveDraftType.EXIT) {
|
||||
//退出页面需判断是否修改了草稿,修改了需弹窗提示
|
||||
if (draftEntity.community.id != mViewModel.mSelectCommunityData?.id
|
||||
|| draftEntity.title != mEditTitle.text.toString()
|
||||
|| mViewModel.articleDraftsContent.value != mRichEditor.html) {
|
||||
showBackDialog()
|
||||
return false
|
||||
}
|
||||
mViewModel.title = mEditTitle.text.toString()
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mViewModel.postArticleDrafts(saveType)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -495,18 +478,15 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
}, 100)
|
||||
}
|
||||
|
||||
private fun showPatchBackDialog() {
|
||||
private fun showBackDialog() {
|
||||
if (mRichEditor.hasPlaceholderImage()) return
|
||||
DialogUtils.showCancelAlertDialog(this, "提示",
|
||||
"即将退出修改,是否需要将此次编辑保存到草稿箱?",
|
||||
"保存草稿",
|
||||
" 继续退出",
|
||||
{
|
||||
mViewModel.title = mEditTitle.text.toString()
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mViewModel.postArticleDrafts(SaveDraftType.EXIT)
|
||||
},
|
||||
{ finish() })
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "是否保存修改内容用于下次编辑?", "不保存", "保存并退出", Gravity.CENTER, true, {
|
||||
finish()
|
||||
}, {
|
||||
mViewModel.title = mEditTitle.text.toString()
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mViewModel.postArticleDrafts(SaveDraftType.EXIT)
|
||||
})
|
||||
}
|
||||
|
||||
private fun showSelectGameDialog() {
|
||||
@ -543,7 +523,7 @@ class ArticleEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
|
||||
mViewModel.content = getReplaceRealContent()
|
||||
mRichEditor.showLinkStyle()
|
||||
if (mRichEditor.hasPlaceholderImage()) {
|
||||
ToastUtils.showToast("图片正在上传中")
|
||||
ToastUtils.showToast("图片上传ing")
|
||||
return@postDelayed
|
||||
}
|
||||
if (mViewModel.checkDataAndLoadTitleTag(mIsKeyBoardShow)) {
|
||||
|
||||
@ -115,6 +115,7 @@ class ArticleEditViewModel(application: Application) : AndroidViewModel(applicat
|
||||
ToastUtils.showToast("帖子最多输入${MAX_ARTICLE_TEXT_LENGTH}个字", if (isKeyBoardShow) Gravity.CENTER else -1)
|
||||
return false
|
||||
}
|
||||
if (detailEntity != null && detailEntity?.title == title && HtmlUtils.stripHtml(detailEntity?.content) == HtmlUtils.stripHtml(content)) return false
|
||||
if (mSelectCommunityData == null) {
|
||||
ToastUtils.showToast("请选择论坛", if (isKeyBoardShow) Gravity.CENTER else -1)
|
||||
notSelectForum.postValue(true)
|
||||
@ -131,32 +132,10 @@ class ArticleEditViewModel(application: Application) : AndroidViewModel(applicat
|
||||
val articleContent = HtmlUtils.stripHtml(content).length
|
||||
if (articleContent < MIN_ARTICLE_TEXT_LENGTH) return false
|
||||
if (articleContent > MAX_ARTICLE_TEXT_LENGTH) return false
|
||||
if (detailEntity != null && detailEntity?.title == title && HtmlUtils.stripHtml(detailEntity?.content) == HtmlUtils.stripHtml(content)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据问题标题获取相应标签(标签默认选中)
|
||||
*/
|
||||
fun loadTitleTags() {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
mApi
|
||||
.getQuestionTagsByTitle(mSelectCommunityData?.id, UrlFilterUtils.getFilterQuery("title", title))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<String>>() {
|
||||
override fun onResponse(response: List<String>?) {
|
||||
titleTags.postValue(response)
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
Utils.toast(getApplication(), R.string.request_failure_normal_hint)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查图片是否符合规则并上传图片
|
||||
* @param picPath 图片本地路径
|
||||
|
||||
@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment
|
||||
import com.gh.base.BaseActivity_TabLayout
|
||||
import com.gh.gamecenter.qa.article.draft.ArticleDraftFragment
|
||||
import com.gh.gamecenter.qa.answer.draft.AnswerDraftFragment
|
||||
import com.gh.gamecenter.qa.questions.draft.QuestionDraftFragment
|
||||
|
||||
class CommunityDraftWrapperActivity : BaseActivity_TabLayout() {
|
||||
|
||||
@ -16,13 +17,13 @@ class CommunityDraftWrapperActivity : BaseActivity_TabLayout() {
|
||||
}
|
||||
|
||||
override fun initFragmentList(fragments: MutableList<Fragment>) {
|
||||
fragments.add(AnswerDraftFragment())
|
||||
fragments.add(ArticleDraftFragment())
|
||||
fragments.add(QuestionDraftFragment())
|
||||
}
|
||||
|
||||
override fun initTabTitleList(tabTitleList: MutableList<String>) {
|
||||
tabTitleList.add("回答草稿")
|
||||
tabTitleList.add("帖子草稿")
|
||||
tabTitleList.add("问题草稿")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -5,6 +5,7 @@ import androidx.annotation.Keep
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.entity.UserEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.qa.entity.ArticleEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -36,6 +37,14 @@ class ArticleViewModel(application: Application, private val articleType: Insert
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if (articleType == InsertArticleWrapperActivity.ArticleType.MINE_ARTICLE) {
|
||||
val userInfoEntity = UserManager.getInstance().userInfoEntity
|
||||
list.forEach {
|
||||
it.user = UserEntity(userInfoEntity?.icon, userInfoEntity?.name, userInfoEntity?.userId,
|
||||
auth = userInfoEntity?.auth, badge = userInfoEntity?.badge)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ class AnswerEntity() : Parcelable {
|
||||
@SerializedName("sequence_id")
|
||||
var sequenceId: String? = null
|
||||
|
||||
@SerializedName("brief", alternate = ["content"])
|
||||
var brief: String? = null
|
||||
|
||||
@SerializedName("title")
|
||||
@ -108,6 +109,10 @@ class AnswerEntity() : Parcelable {
|
||||
@Ignore
|
||||
var description: String? = ""
|
||||
|
||||
@Ignore
|
||||
@SerializedName("popular_answer")
|
||||
var popularAnswer: AnswerEntity? = null
|
||||
|
||||
fun getPassVideos(): List<CommunityVideoEntity> {
|
||||
val passVideos = arrayListOf<CommunityVideoEntity>()
|
||||
for (video in videos) {
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.gamecenter.qa.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class QuestionDraftEntity(
|
||||
@SerializedName("_id")
|
||||
var id: String = "",
|
||||
@SerializedName("community_id")
|
||||
var communityId:String="",
|
||||
var bbs: CommunityEntity? = null,
|
||||
var title: String = "",
|
||||
var description: String = "",
|
||||
var images: ArrayList<String> = arrayListOf(),
|
||||
var videos: ArrayList<CommunityVideoEntity> = arrayListOf(),
|
||||
var tags: List<String> = arrayListOf()
|
||||
) : Parcelable
|
||||
@ -29,7 +29,11 @@ data class QuestionsDetailEntity(var id: String? = null,
|
||||
var me: MeEntity = MeEntity(),
|
||||
@SerializedName("follow_count")
|
||||
private var followCount: Int = 0,
|
||||
var user: UserEntity = UserEntity()) : Parcelable {
|
||||
var user: UserEntity = UserEntity(),
|
||||
//提交问题用
|
||||
@SerializedName("draft_id")
|
||||
var draftId: String = ""
|
||||
) : Parcelable {
|
||||
|
||||
fun getFollowCount(): Int {
|
||||
return if (followCount == 0) 1 else {
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package com.gh.gamecenter.qa.questions.draft
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
|
||||
class QuestionDraftActivity : NormalActivity() {
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context): Intent {
|
||||
val bundle = Bundle()
|
||||
return getTargetIntent(context, QuestionDraftActivity::class.java, QuestionDraftFragment::class.java, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.gh.gamecenter.qa.questions.draft
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.constant.ItemViewType
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.databinding.CommunityQuestionDraftItemBinding
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
|
||||
|
||||
class QuestionDraftAdapter(val context: Context, val mViewModel: QuestionDraftViewModel?,private val selectCallback: (QuestionDraftEntity) -> Unit) : ListAdapter<QuestionDraftEntity>(context) {
|
||||
|
||||
override fun areItemsTheSame(oldItem: QuestionDraftEntity, newItem: QuestionDraftEntity): Boolean {
|
||||
return !TextUtils.isEmpty(oldItem.id) && oldItem.id == newItem.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: QuestionDraftEntity, newItem: QuestionDraftEntity): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (position == itemCount - 1) {
|
||||
ItemViewType.ITEM_FOOTER
|
||||
} else ItemViewType.ITEM_BODY
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val view: View
|
||||
return when (viewType) {
|
||||
ItemViewType.ITEM_FOOTER -> {
|
||||
view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
|
||||
FooterViewHolder(view)
|
||||
}
|
||||
else -> {
|
||||
view = mLayoutInflater.inflate(R.layout.community_question_draft_item, parent, false)
|
||||
QuestionDraftViewHolder(CommunityQuestionDraftItemBinding.bind(view))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is QuestionDraftViewHolder) {
|
||||
val entity = mEntityList[position]
|
||||
holder.binding.data = entity
|
||||
holder.binding.articleDraftDelete.setOnClickListener {
|
||||
DialogUtils.showAlertDialog(mContext, "警告", "确定要删除问题草稿吗?删除之后不可恢复",
|
||||
"确定", "取消", DialogUtils.ConfirmListener {
|
||||
mViewModel?.deleteDraft(entity.id)
|
||||
}, null)
|
||||
}
|
||||
holder.itemView.setOnClickListener {
|
||||
selectCallback.invoke(entity)
|
||||
}
|
||||
} else if (holder is FooterViewHolder) {
|
||||
holder.initItemPadding()
|
||||
holder.initFooterViewHolder(mIsLoading, isNetworkError, mIsOver, R.string.ask_loadover_hint)
|
||||
}
|
||||
}
|
||||
|
||||
class QuestionDraftViewHolder(val binding: CommunityQuestionDraftItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package com.gh.gamecenter.qa.questions.draft
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.util.ToastUtils
|
||||
import com.gh.common.util.checkStoragePermissionBeforeAction
|
||||
import com.gh.common.util.viewModelProvider
|
||||
import com.gh.common.view.CustomDividerItemDecoration
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
import com.gh.gamecenter.baselist.LoadType
|
||||
import com.gh.gamecenter.eventbus.EBReuse
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
|
||||
import com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDraftEntity
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class QuestionDraftFragment : ListFragment<QuestionDraftEntity, QuestionDraftViewModel>() {
|
||||
|
||||
var mAdapter: QuestionDraftAdapter? = null
|
||||
lateinit var mViewModel: QuestionDraftViewModel
|
||||
|
||||
override fun provideListAdapter(): ListAdapter<*> {
|
||||
return mAdapter ?: QuestionDraftAdapter(requireContext(), mViewModel) {
|
||||
if (activity is CommunityDraftWrapperActivity) {
|
||||
checkStoragePermissionBeforeAction {
|
||||
val intent = QuestionEditActivity.getDraftIntent(requireContext(), it)
|
||||
startActivity(intent)
|
||||
}
|
||||
} else {
|
||||
checkStoragePermissionBeforeAction {
|
||||
val intent = Intent()
|
||||
intent.putExtra(QuestionDraftEntity::class.java.simpleName, it)
|
||||
requireActivity().setResult(Activity.RESULT_OK, intent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
mAdapter = this
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideListViewModel(): QuestionDraftViewModel {
|
||||
mViewModel = viewModelProvider()
|
||||
return mViewModel
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (activity is QuestionDraftActivity) {
|
||||
setNavigationTitle("问题草稿")
|
||||
}
|
||||
mViewModel.deleteDraftSuccess.observe(this, Observer { pair ->
|
||||
if (pair.second) {
|
||||
val draftId = pair.first
|
||||
val index = mAdapter?.entityList?.indexOfFirst { it.id == draftId } ?: -1
|
||||
if (index >= 0) {
|
||||
mAdapter?.entityList?.removeAt(index)
|
||||
if (mAdapter?.entityList.isNullOrEmpty()) {
|
||||
mListViewModel.load(LoadType.REFRESH)
|
||||
} else {
|
||||
mAdapter?.notifyItemRemoved(index)
|
||||
}
|
||||
|
||||
ToastUtils.showToast("删除成功")
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun getItemDecoration(): RecyclerView.ItemDecoration? {
|
||||
val insetDivider = ContextCompat.getDrawable(requireContext(), R.drawable.divider_item_line_space_16)
|
||||
val itemDecoration = CustomDividerItemDecoration(requireContext(), notDecorateTheLastItem = true)
|
||||
itemDecoration.setDrawable(insetDivider!!)
|
||||
return itemDecoration
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(reuse: EBReuse) {
|
||||
if (QuestionEditActivity.QUESTION_DRAFT_CHANGE_TAG == reuse.type) {
|
||||
mBaseHandler.postDelayed({ mListViewModel.load(LoadType.REFRESH) }, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.gh.gamecenter.qa.questions.draft
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.util.observableToMain
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class QuestionDraftViewModel(application: Application) : ListViewModel<QuestionDraftEntity, QuestionDraftEntity>(application) {
|
||||
val deleteDraftSuccess = MutableLiveData<Pair<String, Boolean>>()
|
||||
private val api = RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<MutableList<QuestionDraftEntity>> {
|
||||
return api.getQuestionDrafts(UserManager.getInstance().userId)
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteDraft(draftId: String) {
|
||||
api.deleteQuestionDraft(UserManager.getInstance().userId, draftId)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object :Response<ResponseBody>(){
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
deleteDraftSuccess.postValue(Pair(draftId, true))
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
super.onFailure(e)
|
||||
deleteDraftSuccess.postValue(Pair(draftId, false))
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
@ -9,24 +9,18 @@ import android.graphics.Color
|
||||
import android.graphics.LinearGradient
|
||||
import android.graphics.Shader
|
||||
import android.os.Bundle
|
||||
import android.os.Message
|
||||
import android.text.Editable
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
import android.view.KeyEvent
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.*
|
||||
import android.widget.EditText
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.base.ToolBarActivity
|
||||
import com.gh.base.fragment.BaseDialogWrapperFragment
|
||||
import com.gh.base.fragment.WaitingDialogFragment
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.util.*
|
||||
@ -39,17 +33,23 @@ import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.entity.Permissions
|
||||
import com.gh.gamecenter.eventbus.EBReuse
|
||||
import com.gh.gamecenter.mvvm.Status
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleSelectGameAdapter
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleTagsSelectFragment
|
||||
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
|
||||
import com.gh.gamecenter.qa.article.draft.ArticleDraftActivity
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
|
||||
import com.gh.gamecenter.qa.dialog.ChooseForumDialogFragment
|
||||
import com.gh.gamecenter.qa.editor.VideoActivity
|
||||
import com.gh.gamecenter.qa.entity.CommunityVideoEntity
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.qa.questions.draft.QuestionDraftActivity
|
||||
import com.gh.gamecenter.qa.questions.edit.pic.QuestionsEditPicAdapter
|
||||
import com.gh.gamecenter.qa.questions.edit.tip.QuestionTitleTipAdapter
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.Matisse
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONObject
|
||||
import kotlin.math.abs
|
||||
|
||||
@ -66,10 +66,12 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
private var mUploadImageCancelDialog: Dialog? = null
|
||||
private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
|
||||
private lateinit var picAdapter: QuestionsEditPicAdapter
|
||||
private lateinit var mMenuDraft: MenuItem
|
||||
private lateinit var mMenuPost: MenuItem
|
||||
private var mIsExtendedKeyboardShow = false
|
||||
private var mOffset = 0
|
||||
private var mTagsSelectFragment: TagsSelectFragment? = null
|
||||
private var mPostDraftsCount: Int = 0
|
||||
|
||||
private val mSaveTitleKey = "title"
|
||||
private val mSaveContentKey = "content"
|
||||
@ -96,6 +98,25 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
duration = RichEditor.formatVideoDuration(videoEntity.length),
|
||||
status = videoEntity.status))
|
||||
}
|
||||
} else if (requestCode == QUESTION_DRAFT_REQUEST_CODE && resultCode == RESULT_OK) {
|
||||
val draftEntity = data?.getParcelableExtra<QuestionDraftEntity>(QuestionDraftEntity::class.java.simpleName)
|
||||
if (draftEntity != null) {
|
||||
mViewModel.questionDraftEntity = draftEntity
|
||||
setQuestionDraft(draftEntity)
|
||||
mViewModel.getQuestionDraftContent(draftEntity.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
if (msg.what == 1) {
|
||||
if (mViewModel.communityEntity != null
|
||||
&& !mViewModel.title.isNullOrEmpty()
|
||||
&& !mViewModel.content.isNullOrEmpty()) {
|
||||
mViewModel.saveQuestionDraft(SaveDraftType.AUTO)
|
||||
}
|
||||
mBaseHandler.sendEmptyMessageDelayed(1, SAVE_DRAFTS_INTERVAL_TIME.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +125,7 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
|
||||
setToolbarMenu(R.menu.menu_question_post)
|
||||
mToolbar.navigationIcon = null
|
||||
mMenuDraft = mToolbar.menu.findItem(R.id.menu_draft)
|
||||
mMenuPost = mToolbar.menu.findItem(R.id.menu_question_post)
|
||||
mViewModel = ViewModelProviders.of(this).get(QuestionEditViewModel::class.java)
|
||||
if (savedInstanceState != null) {
|
||||
@ -127,24 +149,25 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
if (intent != null) {
|
||||
val communityEntity = intent.getParcelableExtra<CommunityEntity>(CommunityEntity::class.java.simpleName)
|
||||
val detailEntity = intent.getParcelableExtra<QuestionsDetailEntity>(QuestionsDetailEntity::class.java.simpleName)
|
||||
if (detailEntity != null) { // 问题编辑
|
||||
mViewModel.questionEntity = detailEntity
|
||||
mViewModel.communityEntity = detailEntity.community
|
||||
mViewModel.communityEntity?.icon = detailEntity.community.game?.getIcon()
|
||||
mViewModel.communityEntity?.iconSubscript = detailEntity.community.game?.iconSubscript
|
||||
setForumName()
|
||||
mViewModel.content = detailEntity.description
|
||||
mViewModel.picList.postValue(ArrayList(detailEntity.images))
|
||||
mViewModel.isModeratorPatch = intent.getBooleanExtra(EntranceUtils.KEY_QUESTION_MODERATOR_PATCH, false)
|
||||
val videos = detailEntity.videos
|
||||
if (videos.isNotEmpty()) mViewModel.videoLiveData.postValue(detailEntity.videos[0])
|
||||
if (mViewModel.title.isNullOrEmpty()) mViewModel.title = detailEntity.title
|
||||
} else { // 新增问题
|
||||
var searchKey = intent.getStringExtra(EntranceUtils.KEY_QUESTIONS_SEARCH_KEY)
|
||||
if (!searchKey.isNullOrEmpty() && searchKey.length > QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
searchKey = searchKey.substring(0, QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
if (mViewModel.title.isNullOrEmpty()) mViewModel.title = searchKey
|
||||
mViewModel.isFromSearch = intent.getBooleanExtra(QuestionEditViewModel.QUESTION_FORM_SEARCH, false)
|
||||
val draftEntity = intent.getParcelableExtra<QuestionDraftEntity>(QuestionDraftEntity::class.java.simpleName)
|
||||
when {
|
||||
detailEntity != null -> { // 问题编辑
|
||||
setPatchContent(detailEntity)
|
||||
}
|
||||
draftEntity != null -> { //草稿编辑
|
||||
mViewModel.questionDraftEntity = draftEntity
|
||||
setQuestionDraft(draftEntity)
|
||||
mViewModel.getQuestionDraftContent(draftEntity.id)
|
||||
mBaseHandler.sendEmptyMessageDelayed(1, SAVE_DRAFTS_INTERVAL_TIME.toLong())
|
||||
}
|
||||
else -> { // 新增问题
|
||||
var searchKey = intent.getStringExtra(EntranceUtils.KEY_QUESTIONS_SEARCH_KEY)
|
||||
if (!searchKey.isNullOrEmpty() && searchKey.length > QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
searchKey = searchKey.substring(0, QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
if (mViewModel.title.isNullOrEmpty()) mViewModel.title = searchKey
|
||||
mViewModel.isFromSearch = intent.getBooleanExtra(QuestionEditViewModel.QUESTION_FORM_SEARCH, false)
|
||||
mBaseHandler.sendEmptyMessageDelayed(1, SAVE_DRAFTS_INTERVAL_TIME.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
if (communityEntity != null) {
|
||||
@ -152,7 +175,6 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
setForumName()
|
||||
mBinding.chooseForumTv.isEnabled = false
|
||||
mBinding.chooseForumTv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
if (!mViewModel.isFromSearch) mViewModel.checkQuestionDraft()
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +217,7 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
mBinding.questionseditContent.filters = arrayOf(TextHelper.getFilter(300, "内容最多300个字"))
|
||||
mBinding.questionseditContent.addTextChangedListener {
|
||||
mBinding.editorTextNumTv.text = "${mBinding.questionseditContent.text.length}/300"
|
||||
checkPostButtonEnable()
|
||||
}
|
||||
mBinding.questionseditContent.setOnTouchListener { v, event ->
|
||||
closeExtendedKeyboard()
|
||||
@ -236,6 +259,35 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
observeData()
|
||||
}
|
||||
|
||||
private fun setPatchContent(detailEntity: QuestionsDetailEntity) {
|
||||
mMenuDraft.isVisible = false
|
||||
mViewModel.questionEntity = detailEntity
|
||||
mViewModel.communityEntity = detailEntity.community
|
||||
mViewModel.communityEntity?.icon = detailEntity.community.game?.getIcon()
|
||||
mViewModel.communityEntity?.iconSubscript = detailEntity.community.game?.iconSubscript
|
||||
mViewModel.content = detailEntity.description
|
||||
mViewModel.picList.postValue(ArrayList(detailEntity.images))
|
||||
mViewModel.isModeratorPatch = intent.getBooleanExtra(EntranceUtils.KEY_QUESTION_MODERATOR_PATCH, false)
|
||||
val videos = detailEntity.videos
|
||||
if (videos.isNotEmpty()) mViewModel.videoLiveData.postValue(detailEntity.videos[0])
|
||||
if (mViewModel.title.isNullOrEmpty()) mViewModel.title = detailEntity.title
|
||||
setForumName()
|
||||
}
|
||||
|
||||
private fun setQuestionDraft(draftEntity: QuestionDraftEntity) {
|
||||
mViewModel.communityEntity = draftEntity.bbs
|
||||
mViewModel.communityEntity?.icon = draftEntity.bbs?.game?.getIcon()
|
||||
mViewModel.communityEntity?.iconSubscript = draftEntity.bbs?.game?.iconSubscript
|
||||
mViewModel.title = draftEntity.title
|
||||
mViewModel.content = draftEntity.description
|
||||
mViewModel.picList.postValue(draftEntity.images)
|
||||
val videos = draftEntity.videos
|
||||
if (videos.isNotEmpty()) mViewModel.videoLiveData.postValue(videos[0])
|
||||
mBinding.questionseditTitle.setText(mViewModel.title)
|
||||
mBinding.questionseditContent.setText(mViewModel.content)
|
||||
setForumName()
|
||||
}
|
||||
|
||||
private fun observeData() {
|
||||
mViewModel.moderatorPostLiveData.observe(this, Observer {
|
||||
if (it?.status == Status.SUCCESS) {
|
||||
@ -269,6 +321,41 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
toast(R.string.post_failure_hint)
|
||||
}
|
||||
})
|
||||
mViewModel.postQuestionDrafts.observe(this, Observer { pair ->
|
||||
if (pair != null) {
|
||||
when (pair.first) {
|
||||
SaveDraftType.EXIT -> {
|
||||
if (pair.second) {
|
||||
Utils.toast(this, "问题已保存到草稿箱")
|
||||
EventBus.getDefault().post(EBReuse(ArticleEditActivity.ARTICLE_DRAFT_CHANGE_TAG))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
SaveDraftType.AUTO -> {
|
||||
if (pair.second) {
|
||||
if (mPostDraftsCount >= AnswerEditActivity.SAVE_DRAFTS_TOAST_COUNT) {
|
||||
mPostDraftsCount = 0
|
||||
Utils.toast(this, "问题已保存到草稿箱")
|
||||
} else {
|
||||
mPostDraftsCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
SaveDraftType.SKIP -> {
|
||||
if (pair.second) {
|
||||
Utils.toast(this, "问题已保存到草稿箱")
|
||||
startActivityForResult(ArticleDraftActivity.getIntent(this), ArticleEditActivity.ARTICLE_DRAFT_REQUEST_CODE)
|
||||
} else {
|
||||
Utils.toast(this, "问题草稿保存失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
mViewModel.questionDraftsContent.observe(this, Observer {
|
||||
mViewModel.questionDraftEntity = it
|
||||
setQuestionDraft(it)
|
||||
})
|
||||
|
||||
// Process dialog
|
||||
mViewModel.processDialog.observe(this, Observer { it ->
|
||||
@ -419,23 +506,30 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(menuItem: MenuItem?): Boolean {
|
||||
if (mViewModel.isModeratorPatch) {
|
||||
if (checkSameFromQuestionData()) {
|
||||
toast("内容没有变化")
|
||||
if (menuItem?.itemId == R.id.menu_question_post) {
|
||||
if (mViewModel.isModeratorPatch) {
|
||||
if (checkSameFromQuestionData()) {
|
||||
toast("内容没有变化")
|
||||
} else {
|
||||
mViewModel.selectedTags.addAll(mViewModel.questionEntity?.tags!!)
|
||||
DialogUtils.showAlertDialog(this, "修改问题",
|
||||
if (mViewModel.questionEntity!!.me.moderatorPermissions.updateQuestion == Permissions.REPORTER)
|
||||
"你的操作将提交给小编审核,确定提交吗?" else "你的操作将立即生效,确定提交吗?(你的管理权限为:高级)",
|
||||
"确定", "取消", DialogUtils.ConfirmListener {
|
||||
mViewModel.uploadPicAndPatchQuestion(false)
|
||||
}, null)
|
||||
}
|
||||
} else {
|
||||
mViewModel.selectedTags.addAll(mViewModel.questionEntity?.tags!!)
|
||||
DialogUtils.showAlertDialog(this, "修改问题",
|
||||
if (mViewModel.questionEntity!!.me.moderatorPermissions.updateQuestion == Permissions.REPORTER)
|
||||
"你的操作将提交给小编审核,确定提交吗?" else "你的操作将立即生效,确定提交吗?(你的管理权限为:高级)",
|
||||
"确定", "取消", DialogUtils.ConfirmListener {
|
||||
mViewModel.uploadPicAndPatchQuestion(false)
|
||||
}, null)
|
||||
if (mViewModel.checkTitleAndLoadTitleTag()) {
|
||||
mTagsSelectFragment?.postQuestion()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mViewModel.checkTitleAndLoadTitleTag()) {
|
||||
mTagsSelectFragment?.postQuestion()
|
||||
} else if (menuItem?.itemId == R.id.menu_draft) {
|
||||
if (checkDraft(SaveDraftType.SKIP)) {
|
||||
startActivityForResult(QuestionDraftActivity.getIntent(this), QUESTION_DRAFT_REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -466,7 +560,6 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
mViewModel.questionEntity?.community?.name = it.name
|
||||
}
|
||||
setForumName()
|
||||
if (!mViewModel.isFromSearch) mViewModel.checkQuestionDraft()
|
||||
mBinding.vm = mViewModel
|
||||
}
|
||||
}
|
||||
@ -513,8 +606,6 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
}
|
||||
// 需要检查的内容,其中任意一个不为空都要打开提示弹窗
|
||||
val imgList = mViewModel.picList.value
|
||||
val title = mBinding.questionseditTitle.text.toString().trim()
|
||||
val content = mBinding.questionseditContent.text.toString().trim()
|
||||
|
||||
if (mViewModel.isModeratorPatch) {
|
||||
if (checkSameFromQuestionData()) {
|
||||
@ -524,21 +615,62 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
, "确定退出修改?已编辑的内容将丢失"
|
||||
, "继续编辑", " 退出", null) { finish() }
|
||||
return true
|
||||
} else if (imgList != null && imgList.size > 0 || title.isNotEmpty() || content.isNotEmpty()) {
|
||||
if (mViewModel.questionEntity == null && !mViewModel.isFromSearch) {
|
||||
mViewModel.saveQuestionDraft()
|
||||
toast("问题草稿已保存")
|
||||
}
|
||||
|
||||
//问题发布
|
||||
if (mViewModel.questionEntity == null && mViewModel.questionDraftEntity == null) {
|
||||
if (mViewModel.communityEntity != null && (!imgList.isNullOrEmpty() || !mViewModel.title.isNullOrEmpty() || !mViewModel.content.isNullOrEmpty())) {
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "是否保存内容再退出?", "不保存", "保存并退出", Gravity.CENTER, true, {
|
||||
finish()
|
||||
}, {
|
||||
mViewModel.saveQuestionDraft(SaveDraftType.EXIT)
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
//问题编辑,需要判断是否修改过
|
||||
if (mViewModel.questionEntity != null) {
|
||||
return if (mViewModel.questionEntity?.community?.id != mViewModel.communityEntity?.id
|
||||
|| mViewModel.questionEntity?.title != mViewModel.title
|
||||
|| mViewModel.questionEntity?.description != mViewModel.content) {
|
||||
showBackDialog()
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
return !checkDraft(SaveDraftType.EXIT)
|
||||
}
|
||||
|
||||
private fun checkDraft(saveType: SaveDraftType): Boolean {
|
||||
val draftEntity = mViewModel.questionDraftEntity ?: return true
|
||||
if (draftEntity.title.isEmpty() && draftEntity.description.isEmpty()) return true
|
||||
if (saveType == SaveDraftType.SKIP) {
|
||||
//判断是否修改了草稿,修改了需自动保存无需提示
|
||||
if (draftEntity.bbs?.id != mViewModel.communityEntity?.id
|
||||
|| draftEntity.title != mViewModel.title
|
||||
|| draftEntity.description != mViewModel.content) {
|
||||
mViewModel.saveQuestionDraft(SaveDraftType.AUTO)
|
||||
return true
|
||||
}
|
||||
} else if (saveType == SaveDraftType.EXIT) {
|
||||
//退出页面需判断是否修改了草稿,修改了需弹窗提示
|
||||
if (draftEntity.bbs?.id != mViewModel.communityEntity?.id
|
||||
|| draftEntity.title != mViewModel.title
|
||||
|| draftEntity.description != mViewModel.content) {
|
||||
showBackDialog()
|
||||
return false
|
||||
}
|
||||
|
||||
DialogUtils.showCancelAlertDialog(this, "提示"
|
||||
, if (mViewModel.questionEntity == null) "确定放弃提问吗?" else "确定放弃修改吗?"
|
||||
, "再想想", " 放弃", null) { finish() }
|
||||
return true
|
||||
} else if (mViewModel.questionEntity == null && !mViewModel.isFromSearch) {
|
||||
mViewModel.cleanCurrentCommunityDraft()
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun showBackDialog() {
|
||||
DialogUtils.showNewAlertDialog(this, "提示", "是否保存修改内容用于下次编辑?", "不保存", "保存并退出", Gravity.CENTER, true,{
|
||||
finish()
|
||||
}, {
|
||||
mViewModel.saveQuestionDraft(SaveDraftType.EXIT)
|
||||
})
|
||||
}
|
||||
|
||||
private fun checkSameFromQuestionData(): Boolean {
|
||||
@ -594,6 +726,9 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
|
||||
companion object {
|
||||
const val QUESTION_POSTED_TAG = "QUESTION_POSTED_TAG"
|
||||
const val QUESTION_DRAFT_REQUEST_CODE = 105
|
||||
const val QUESTION_DRAFT_CHANGE_TAG = "ANSWER_DRAFT_CHANGE_TAG"
|
||||
const val SAVE_DRAFTS_INTERVAL_TIME = 15000
|
||||
|
||||
// searchKey 补充到标题(新增问题)
|
||||
fun getIntent(context: Context, searchKey: String?): Intent {
|
||||
@ -630,5 +765,19 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
return intent
|
||||
}
|
||||
|
||||
//编辑草稿
|
||||
@JvmStatic
|
||||
fun getDraftIntent(context: Context, questionDraftEntity: QuestionDraftEntity): Intent {
|
||||
val intent = Intent(context, QuestionEditActivity::class.java)
|
||||
intent.putExtra(QuestionDraftEntity::class.java.simpleName, questionDraftEntity)
|
||||
return intent
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class SaveDraftType {
|
||||
EXIT, // 退出时保存
|
||||
AUTO, // 自动保存
|
||||
SKIP // 跳转至草稿箱时保存
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.gamecenter.qa.questions.edit
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
@ -12,11 +13,16 @@ import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.Permissions
|
||||
import com.gh.gamecenter.entity.User
|
||||
import com.gh.gamecenter.eventbus.EBReuse
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.mvvm.Resource
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDraftEntity
|
||||
import com.gh.gamecenter.qa.entity.CommunityVideoEntity
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.retrofit.service.ApiService
|
||||
@ -50,6 +56,8 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
val moderatorPostLiveData = MediatorLiveData<Resource<String>>()
|
||||
val videoLiveData = MutableLiveData<CommunityVideoEntity>()
|
||||
val notSelectForum = MutableLiveData<Boolean>()
|
||||
val postQuestionDrafts = MediatorLiveData<Pair<QuestionEditActivity.SaveDraftType, Boolean>>()
|
||||
val questionDraftsContent = MutableLiveData<QuestionDraftEntity>()
|
||||
|
||||
var uploadImageSubscription: Disposable? = null
|
||||
|
||||
@ -58,9 +66,10 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
var content: String? = ""
|
||||
|
||||
// picList 纯粹用于展示,可以包含本地和网络地址的图片
|
||||
val picList = MediatorLiveData<MutableList<String>>()
|
||||
val picList = MediatorLiveData<ArrayList<String>>()
|
||||
var defaultTags: MutableList<String> = ArrayList()
|
||||
var questionEntity: QuestionsDetailEntity? = null
|
||||
var questionDraftEntity: QuestionDraftEntity? = null
|
||||
val selectedTags: MutableList<String> = ArrayList()
|
||||
val selectedTagsChange = MediatorLiveData<Boolean>()
|
||||
|
||||
@ -118,6 +127,8 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
Utils.toast(getApplication(), "标题至少${QUESTION_TITLE_MIN_LENGTH}个字")
|
||||
return false
|
||||
}
|
||||
if (questionEntity != null && questionEntity?.title == title && questionEntity?.description == content) return false
|
||||
|
||||
if (TextUtils.isEmpty(communityEntity?.id) || TextUtils.isEmpty(communityEntity?.name)) {
|
||||
Utils.toast(getApplication(), "论坛不能为空")
|
||||
notSelectForum.postValue(true)
|
||||
@ -140,31 +151,10 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
// 检查标题长度限制
|
||||
title?.trim()
|
||||
if (title!!.length < QUESTION_TITLE_MIN_LENGTH) return false
|
||||
if (questionEntity != null && questionEntity?.title == title && questionEntity?.description == content) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据问题标题获取相应标签(标签默认选中)
|
||||
*/
|
||||
private fun loadTitleTags() {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
mApiService
|
||||
.getQuestionTagsByTitle(communityEntity?.id, UrlFilterUtils.getFilterQuery("title", title))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<String>>() {
|
||||
override fun onResponse(response: List<String>?) {
|
||||
titleTags.postValue(response)
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
Utils.toast(getApplication(), R.string.request_failure_normal_hint)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择动作(选中标签/移除已选中的标签)
|
||||
*/
|
||||
@ -353,7 +343,9 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
entity.images = successfullyUploadedPicList
|
||||
val video: CommunityVideoEntity? = videoLiveData.value
|
||||
if (video != null) entity.videos = arrayListOf(video)
|
||||
|
||||
if (!questionDraftEntity?.id.isNullOrEmpty()) {
|
||||
entity.draftId = questionDraftEntity?.id ?: ""
|
||||
}
|
||||
val observable = if (questionEntity != null) {
|
||||
if (!isModeratorPatch) {
|
||||
questionEntity?.images = entity.images
|
||||
@ -384,16 +376,18 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
MtaHelper.onEvent("发表问题", "提交成功", communityEntity?.name)
|
||||
val data = response?.string()
|
||||
val data = response?.string() ?: ""
|
||||
postLiveData.postValue(Resource.success(data))
|
||||
EventBus.getDefault().post(EBReuse(QuestionEditActivity.QUESTION_POSTED_TAG))
|
||||
if (questionEntity == null && !isFromSearch) cleanCurrentCommunityDraft()
|
||||
|
||||
if (questionEntity == null) {
|
||||
tryWithDefaultCatch {
|
||||
EnergyTaskHelper.postEnergyTask("post_question", JSONObject(data).optString("_id"))
|
||||
}
|
||||
}
|
||||
if (!questionDraftEntity?.id.isNullOrEmpty()) {
|
||||
EventBus.getDefault().post(EBReuse(QuestionEditActivity.QUESTION_DRAFT_CHANGE_TAG))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
@ -440,65 +434,63 @@ class QuestionEditViewModel(application: Application) : AndroidViewModel(applica
|
||||
})
|
||||
}
|
||||
|
||||
fun cleanCurrentCommunityDraft() {
|
||||
val draftKey = getDraftKey()
|
||||
if (draftKey.isNullOrEmpty()) {
|
||||
//Utils.toast(getApplication(), "删除草稿失败")
|
||||
return
|
||||
@SuppressLint("CheckResult")
|
||||
fun saveQuestionDraft(saveType: QuestionEditActivity.SaveDraftType) {
|
||||
val body = getQuestionBody()
|
||||
val observable = if (!questionDraftEntity?.id.isNullOrEmpty()) {
|
||||
mApiService.updateQuestionDraft(UserManager.getInstance().userId, questionDraftEntity?.id, body)
|
||||
} else {
|
||||
mApiService.addQuestionDraft(UserManager.getInstance().userId, body)
|
||||
}
|
||||
SPUtils.remove(draftKey)
|
||||
observable
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
val string = data.string()
|
||||
if (!string.isNullOrEmpty() && questionDraftEntity?.id.isNullOrEmpty()) {
|
||||
if (questionDraftEntity == null) questionDraftEntity = QuestionDraftEntity()
|
||||
questionDraftEntity?.id = JSONObject(string).getString("_id")
|
||||
}
|
||||
postQuestionDrafts.postValue(Pair(saveType, true))
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
postQuestionDrafts.postValue(Pair(saveType, false))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun saveQuestionDraft() {
|
||||
val draftKey = getDraftKey()
|
||||
if (draftKey.isNullOrEmpty()) {
|
||||
Utils.toast(getApplication(), "保存草稿失败")
|
||||
return
|
||||
}
|
||||
|
||||
val draftJson = JSONObject()
|
||||
draftJson.put("title", title)
|
||||
draftJson.put("content", content)
|
||||
draftJson.put("images", JSONArray(picList.value))
|
||||
SPUtils.setString(draftKey, draftJson.toString())
|
||||
private fun getQuestionBody(): RequestBody {
|
||||
val draftEntity = QuestionDraftEntity(
|
||||
communityId = communityEntity?.id ?: "",
|
||||
tags = selectedTags.toList(),
|
||||
images = picList.value ?: arrayListOf(),
|
||||
videos = if (videoLiveData.value != null) arrayListOf(videoLiveData.value!!) else arrayListOf(),
|
||||
title = title ?: "",
|
||||
description = content ?: ""
|
||||
)
|
||||
return draftEntity.toRequestBody()
|
||||
}
|
||||
|
||||
fun checkQuestionDraft() {
|
||||
val draftKey = getDraftKey()
|
||||
if (draftKey.isNullOrEmpty()) {
|
||||
Utils.toast(getApplication(), "获取草稿失败")
|
||||
return
|
||||
}
|
||||
@SuppressLint("CheckResult")
|
||||
fun getQuestionDraftContent(draftId: String) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
|
||||
mApiService.getQuestionDraft(UserManager.getInstance().userId, draftId)
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<QuestionDraftEntity>() {
|
||||
override fun onSuccess(data: QuestionDraftEntity) {
|
||||
questionDraftsContent.postValue(data)
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
|
||||
}
|
||||
|
||||
val draft = SPUtils.getString(draftKey, "")
|
||||
if (draft.isNullOrEmpty()) return
|
||||
val draftJson = JSONObject(draft)
|
||||
|
||||
val draftTitle = draftJson.optString("title")
|
||||
if (draftTitle.isNotEmpty()) title = draftTitle
|
||||
|
||||
val draftContent = draftJson.optString("content")
|
||||
if (draftContent.isNotEmpty()) content = draftContent
|
||||
|
||||
val draftImages = draftJson.optJSONArray("images")
|
||||
if (draftImages != null) {
|
||||
val images = ArrayList<String>()
|
||||
for (i in 0 until draftImages.length()) {
|
||||
val img = draftImages.getString(i)
|
||||
if (img.isNotEmpty() && File(img).exists()) {
|
||||
images.add(img)
|
||||
}
|
||||
}
|
||||
if (images.isNotEmpty()) picList.postValue(images)
|
||||
}
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getDraftKey(): String? {
|
||||
if (communityEntity?.id.isNullOrEmpty()) return null
|
||||
return QUESTION_DRAFT_KEY + communityEntity?.id
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
const val QUESTION_TAG_MAX_COUNT = 5
|
||||
const val PIC_MAX_AMOUNT = 30
|
||||
|
||||
@ -223,28 +223,25 @@ class TagsSelectFragment : BaseFragment<String>() {
|
||||
// 添加标签
|
||||
val mDefaultTag = mViewModel?.defaultTags ?: ArrayList()
|
||||
|
||||
if (mViewModel?.questionEntity == null) {
|
||||
val mTitleTag = (mViewModel?.titleTags?.value ?: ArrayList()) as MutableList
|
||||
// 添加默认标签(如果标题标签与默认标签重复则选中)
|
||||
for (s in mDefaultTag.reversed()) {
|
||||
val contains = mTitleTag.contains(s)
|
||||
addTag(s, contains)
|
||||
if (contains) mTitleTag.remove(s)
|
||||
val tags = when {
|
||||
mViewModel?.questionEntity != null -> {
|
||||
mViewModel?.questionEntity?.tags ?: arrayListOf()
|
||||
}
|
||||
// 未匹配到默认标签的默认选中在前排
|
||||
for (s in mTitleTag) {
|
||||
addTag(s, true)
|
||||
mViewModel?.questionDraftEntity != null -> {
|
||||
mViewModel?.questionDraftEntity?.tags ?: arrayListOf()
|
||||
}
|
||||
} else {
|
||||
val tags = mViewModel?.questionEntity?.tags ?: ArrayList()
|
||||
for (s in mDefaultTag) {
|
||||
if (!tags.contains(s))
|
||||
addTag(s, false)
|
||||
}
|
||||
for (s in tags.reversed()) {
|
||||
addTag(s, true)
|
||||
else -> {
|
||||
arrayListOf()
|
||||
}
|
||||
}
|
||||
|
||||
for (s in mDefaultTag) {
|
||||
if (!tags.contains(s))
|
||||
addTag(s, false)
|
||||
}
|
||||
for (s in tags.reversed()) {
|
||||
addTag(s, true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showAddTagDialog() {
|
||||
|
||||
@ -100,6 +100,7 @@ import com.gh.gamecenter.qa.entity.CommunitySelectEntity;
|
||||
import com.gh.gamecenter.qa.entity.CommunitySelectOpenEntity;
|
||||
import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity;
|
||||
import com.gh.gamecenter.qa.entity.InviteEntity;
|
||||
import com.gh.gamecenter.qa.entity.QuestionDraftEntity;
|
||||
import com.gh.gamecenter.qa.entity.QuestionHistoryDetailEntity;
|
||||
import com.gh.gamecenter.qa.entity.QuestionHistoryEntity;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
@ -108,6 +109,7 @@ import com.gh.gamecenter.qa.entity.QuestionsIndexEntity;
|
||||
import com.gh.gamecenter.qa.entity.SearchHottestEntity;
|
||||
import com.gh.gamecenter.qa.entity.SearchNewestEntity;
|
||||
import com.gh.gamecenter.qa.entity.SuggestedFollowEntity;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -2808,4 +2810,34 @@ public interface ApiService {
|
||||
*/
|
||||
@GET("shop/orders/roll_notices")
|
||||
Single<List<RollNoticeEntity>> getRollNotices();
|
||||
|
||||
/**
|
||||
* 新增一个问题草稿
|
||||
*/
|
||||
@POST("users/{user_id}/question_drafts")
|
||||
Single<ResponseBody> addQuestionDraft(@Path("user_id") String userId, @Body RequestBody body);
|
||||
|
||||
/**
|
||||
* 获取单个问题草稿
|
||||
*/
|
||||
@GET("users/{user_id}/question_drafts/{draft_id}")
|
||||
Single<QuestionDraftEntity> getQuestionDraft(@Path("user_id") String userId, @Path("draft_id") String draftId);
|
||||
|
||||
/**
|
||||
* 修改一个问题草稿
|
||||
*/
|
||||
@POST("users/{user_id}/question_drafts/{draft_id}")
|
||||
Single<ResponseBody> updateQuestionDraft(@Path("user_id") String userId, @Path("draft_id") String draftId, @Body RequestBody body);
|
||||
|
||||
/**
|
||||
* 获取问题草稿列表
|
||||
*/
|
||||
@GET("users/{user_id}/question_drafts")
|
||||
Observable<List<QuestionDraftEntity>> getQuestionDrafts(@Path("user_id") String userId);
|
||||
|
||||
/**
|
||||
* 删除单个问题草稿
|
||||
*/
|
||||
@DELETE("users/{user_id}/question_drafts/{draft_id}")
|
||||
Observable<ResponseBody> deleteQuestionDraft(@Path("user_id") String userId, @Path("draft_id") String draftId);
|
||||
}
|
||||
Reference in New Issue
Block a user