diff --git a/app/src/main/java/com/gh/common/DefaultJsApi.kt b/app/src/main/java/com/gh/common/DefaultJsApi.kt index 056b2e0339..7b673f09d4 100644 --- a/app/src/main/java/com/gh/common/DefaultJsApi.kt +++ b/app/src/main/java/com/gh/common/DefaultJsApi.kt @@ -8,9 +8,11 @@ import com.gh.base.CurrentActivityHolder import com.gh.common.util.* import com.gh.gamecenter.LoginActivity import com.gh.gamecenter.ViewImageActivity +import com.gh.gamecenter.entity.Badge import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.retrofit.BiResponse import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.gamecenter.room.AppDatabase import com.gh.gamecenter.user.LoginTag import com.halo.assistant.HaloApp import com.lightgame.utils.Utils @@ -56,6 +58,15 @@ class DefaultJsApi(var context: Context) { context.startActivity(intent) } + @JavascriptInterface + fun refreshUserInfoBadge(msg: Any) { + val badge = msg.toString().toObject() ?: Badge() + val userInfoEntity = UserManager.getInstance().userInfoEntity + userInfoEntity.badge = badge + UserManager.getInstance().userInfoEntity = userInfoEntity + AppDatabase.getInstance(context).userInfoDao().updateUserInfo(userInfoEntity) + } + @JavascriptInterface fun getChannel(msg: Any): String { return HaloApp.getInstance().channel diff --git a/app/src/main/java/com/gh/common/util/StringUtils.java b/app/src/main/java/com/gh/common/util/StringUtils.java index 29c6e2325c..407b036fb0 100644 --- a/app/src/main/java/com/gh/common/util/StringUtils.java +++ b/app/src/main/java/com/gh/common/util/StringUtils.java @@ -70,4 +70,49 @@ public class StringUtils { } return text; } + + /** + * 删除尾部\n字符 + * + * @param str + * @return + */ + public static String deleteStringTailLineBreak(String str) { + if (TextUtils.isEmpty(str)) { + return str; + } + + if (str.length() == 1) { + char ch = str.charAt(0); + if (ch == '\n') { + return ""; + } + return str; + } + + int lastIdx = str.length() - 1; + char last = str.charAt(lastIdx); + + if (last == '\n') { + return str.substring(0, lastIdx); + } else { + return str; + } + } + + /** + * 判断字符串末尾是否有\n + * @param str + * @return + */ + public static boolean isStringTailHasLineBreak(String str) { + if (TextUtils.isEmpty(str)) { + return false; + } + + int lastIdx = str.length() - 1; + char last = str.charAt(lastIdx); + + return last == '\n'; + } } diff --git a/app/src/main/java/com/gh/gamecenter/entity/BadgeConverter.kt b/app/src/main/java/com/gh/gamecenter/entity/BadgeConverter.kt new file mode 100644 index 0000000000..32f2e034b2 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/entity/BadgeConverter.kt @@ -0,0 +1,16 @@ +package com.gh.gamecenter.entity + +import androidx.room.TypeConverter +import com.google.gson.Gson + +class BadgeConverter { + @TypeConverter + fun toBadge(badge: Badge?): String? { + return Gson().toJson(badge) + } + + @TypeConverter + fun fromBadge(badge: String?): Badge? { + return Gson().fromJson(badge, Badge::class.java) + } +} diff --git a/app/src/main/java/com/gh/gamecenter/entity/UserInfoEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/UserInfoEntity.kt index 0cb8ac5fee..5cad57a0d5 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/UserInfoEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/UserInfoEntity.kt @@ -41,4 +41,7 @@ class UserInfoEntity { @TypeConverters(AuthConverter::class) var auth: Auth? = null + + @TypeConverters(BadgeConverter::class) + var badge: Badge? = null } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingCommentItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingCommentItemViewHolder.kt index 118a1900ac..536122a46b 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingCommentItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingCommentItemViewHolder.kt @@ -125,8 +125,8 @@ class RatingCommentItemViewHolder(val binding: RatingCommentItemBinding) : BaseR } }) } else { - name = "${commentData.replyData?.user?.name}:${commentData.replyData?.content}" - contentSpan = getSpan(context, name, commentData) + name = "${commentData.replyData?.user?.name}:${commentData.replyData?.content}" + contentSpan = getSpan(context, name, commentData) replyContent.text = contentSpan } @@ -232,7 +232,7 @@ class RatingCommentItemViewHolder(val binding: RatingCommentItemBinding) : BaseR } } - private fun getSpan(context: Context,name: String, commentData: RatingComment): SpannableStringBuilder { + private fun getSpan(context: Context, name: String, commentData: RatingComment): SpannableStringBuilder { val spanned = SpanBuilder(name) .color(context, 0, commentData.replyData?.user?.name!!.length, R.color.text_3A3A3A) .bold(0, commentData.replyData?.user?.name!!.length) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyAdapter.kt index 8d3890e8ae..b501235a12 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyAdapter.kt @@ -7,6 +7,7 @@ import android.graphics.Color import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.net.Uri +import android.text.SpannableStringBuilder import android.text.Spanned import android.text.TextPaint import android.text.style.ClickableSpan @@ -37,6 +38,7 @@ import com.gh.gamecenter.databinding.RatingReplyItemBinding import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.entity.RatingComment import com.gh.gamecenter.entity.RatingReplyEntity +import com.gh.gamecenter.entity.UserEntity import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.manager.UserManager import com.lightgame.download.DownloadStatus @@ -45,6 +47,7 @@ import com.m7.imkfsdk.utils.DensityUtil import com.squareup.picasso.MemoryPolicy import com.squareup.picasso.NetworkPolicy import com.squareup.picasso.Picasso +import com.squareup.picasso.Target class RatingReplyAdapter(context: Context, val entrance: String, @@ -243,42 +246,21 @@ class RatingReplyAdapter(context: Context, ?: "", copyClickedText = true) val parent = replyEntity.parent if (parent != null) { - var replyName = "${replyEntity.user.name} 回复 ${parent.user.name}" - var replyNameSpannable = SpanBuilder(replyName).color(mContext, replyEntity.user.name!!.length + 4, replyEntity.user.name!!.length + 6, R.color.text_9a9a9a).build() - if (replyEntity.user.badge != null) { - Picasso.with(mContext).load(Uri.parse(replyEntity.user.badge.icon)) - .priority(Picasso.Priority.HIGH) - .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) - .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) - .into(object:com.squareup.picasso.Target{ - override fun onPrepareLoad(placeHolderDrawable: Drawable?) { - - } - - override fun onBitmapFailed(errorDrawable: Drawable?) { - - } - - override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { - val bitmapDrawable = BitmapDrawable(mContext.resources, bitmap) - bitmapDrawable.setBounds(0, 0, DensityUtil.dip2px(16F), DensityUtil.dip2px(16F)) - replyNameSpannable.setSpan(CenterImageSpan(bitmapDrawable), replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - replyNameSpannable.setSpan(object : ClickableSpan() { - override fun updateDrawState(ds: TextPaint) { - super.updateDrawState(ds) - ds.isUnderlineText = false - } - - override fun onClick(widget: View) { - MtaHelper.onEvent("进入徽章墙_用户记录", "游戏评论详情", "${replyEntity.user.name}(${replyEntity.user.id})") - DirectUtils.directToBadgeWall(mContext, replyEntity.user.id, replyEntity.user.name, replyEntity.user.icon) - } - - }, replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - userName.movementMethod= CustomLinkMovementMethod.getInstance() - userName.text = replyNameSpannable - } - }) + var replyName: String + var replyNameSpannable: SpannableStringBuilder + if (replyEntity.user.badge != null && replyEntity.parent.user.badge == null) { + replyName = "${replyEntity.user.name} 回复 ${parent.user.name}" + replyNameSpannable = SpanBuilder(replyName).color(mContext, replyEntity.user.name!!.length + 4, replyEntity.user.name!!.length + 6, R.color.text_9a9a9a).build() + setBadgeSpan(replyEntity.user, replyNameSpannable, replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 2) + } else if (replyEntity.user.badge == null && replyEntity.parent.user.badge != null) { + replyName = "${replyEntity.user.name} 回复 ${parent.user.name} " + replyNameSpannable = SpanBuilder(replyName).color(mContext, replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 4, R.color.text_9a9a9a).build() + setBadgeSpan(parent.user, replyNameSpannable, replyEntity.user.name!!.length + parent.user.name!!.length + 3, replyEntity.user.name!!.length + parent.user.name!!.length + 4) + } else if (replyEntity.user.badge != null && replyEntity.parent.user.badge != null) { + replyName = "${replyEntity.user.name} 回复 ${parent.user.name} " + replyNameSpannable = SpanBuilder(replyName).color(mContext, replyEntity.user.name!!.length + 4, replyEntity.user.name!!.length + 6, R.color.text_9a9a9a).build() + setBadgeSpan(replyEntity.user, replyNameSpannable, replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 2) + setBadgeSpan(parent.user, replyNameSpannable, replyEntity.user.name!!.length + parent.user.name!!.length + 8, replyEntity.user.name!!.length + parent.user.name!!.length + 9) } else { replyName = "${replyEntity.user.name} 回复 ${parent.user.name}" replyNameSpannable = SpanBuilder(replyName).color(mContext, replyEntity.user.name!!.length + 1, replyEntity.user.name!!.length + 4, R.color.text_9a9a9a).build() @@ -417,6 +399,42 @@ class RatingReplyAdapter(context: Context, } } + private fun RatingReplyItemBinding.setBadgeSpan(user: UserEntity, replyNameSpannable: SpannableStringBuilder, startIndex: Int, endIndex: Int) { + Picasso.with(mContext).load(Uri.parse(user.badge?.icon)) + .priority(Picasso.Priority.HIGH) + .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) + .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) + .into(object : Target { + override fun onPrepareLoad(placeHolderDrawable: Drawable?) { + + } + + override fun onBitmapFailed(errorDrawable: Drawable?) { + + } + + override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { + val bitmapDrawable = BitmapDrawable(mContext.resources, bitmap) + bitmapDrawable.setBounds(0, 0, DensityUtil.dip2px(16F), DensityUtil.dip2px(16F)) + replyNameSpannable.setSpan(CenterImageSpan(bitmapDrawable), startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + replyNameSpannable.setSpan(object : ClickableSpan() { + override fun updateDrawState(ds: TextPaint) { + super.updateDrawState(ds) + ds.isUnderlineText = false + } + + override fun onClick(widget: View) { + MtaHelper.onEvent("进入徽章墙_用户记录", "游戏评论详情", "${user.name}(${user.id})") + DirectUtils.directToBadgeWall(mContext, user.id, user.name, user.icon) + } + + }, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + userName.movementMethod = CustomLinkMovementMethod.getInstance() + userName.text = replyNameSpannable + } + }) + } + fun handleSyncData(intent: Intent?) { SyncDataBetweenPageHelper.resultHandle(intent, object : OnSyncCallBack { override fun onData(dataPosition: Int): RatingComment? { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt index dce1c5c730..91b3ed10ad 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.text.TextUtils import android.view.MenuItem import android.view.View +import android.widget.RelativeLayout import androidx.core.widget.NestedScrollView import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders @@ -30,8 +31,9 @@ import okhttp3.MediaType import okhttp3.RequestBody import org.json.JSONObject import java.util.regex.Pattern +import kotlin.math.abs -class RatingEditActivity : ToolBarActivity() { +class RatingEditActivity : ToolBarActivity(),KeyboardHeightObserver { private var mPostDialog: WaitingDialogFragment? = null private var mInstallPackageName: String? = null @@ -47,6 +49,8 @@ class RatingEditActivity : ToolBarActivity() { private lateinit var mEditCommentAdapter: EditCommentAdapter private lateinit var mViewModel: RatingEditViewModel + private var mKeyboardHeightProvider: KeyboardHeightProvider? = null + private var mOffset: Int = 0 override fun getLayoutId(): Int { return R.layout.activity_rating_edit @@ -66,14 +70,16 @@ class RatingEditActivity : ToolBarActivity() { mBinding = ActivityRatingEditBinding.bind(mContentView) initView() + mKeyboardHeightProvider = KeyboardHeightProvider(this) + mBinding.root.post { mKeyboardHeightProvider?.start() } mViewModel.deviceName.observe(this, Observer { mBinding.deviceName.text = it }) mViewModel.guideTags.observe(this, Observer { mCommentLabelAdapter.setListData(it) - mBinding.viewShadow.goneIf(mCommentLabelAdapter.itemCount == 0) - mBinding.rvLabel.goneIf(mCommentLabelAdapter.itemCount == 0) +// mBinding.viewShadow.goneIf(mCommentLabelAdapter.itemCount == 0) +// mBinding.rvLabel.goneIf(mCommentLabelAdapter.itemCount == 0) }) mViewModel.getDeviceName() @@ -82,7 +88,7 @@ class RatingEditActivity : ToolBarActivity() { private fun initView() { mBinding.game = mGame - mBinding.content.hint = "您觉得《${mGame.name}》怎么样?真实、客观、丰富、大于100字符的评论内容,更容易获得点赞并推荐到安利墙哦~" + mBinding.content.hint = "您觉得《${mGame.name}》怎么样?真实、客观、丰富、大于100字的评论内容,更容易获得点赞并推荐到安利墙哦~" mBinding.content.filters = arrayOf(TextHelper.getFilter(RATING_CONTENT_LIMIT, "最多" + RATING_CONTENT_LIMIT + "个字")) mBinding.commentRules.setOnClickListener { startActivity(WebActivity.getCommentRulesIntent(this)) @@ -96,15 +102,29 @@ class RatingEditActivity : ToolBarActivity() { } mCommentLabelAdapter.clickListener = { label, pos -> mCommentLabelAdapter.addSelectLabel(label) + + for (item in mEditCommentAdapter.getListData()) { - item.comment = item.comment.replace("\n", "") + var newString = item.comment + while (true) { + if (StringUtils.isStringTailHasLineBreak(newString)) { + newString = StringUtils.deleteStringTailLineBreak(newString) + } else { + item.comment = newString + break + } + } + } + if (mEditCommentAdapter.getListData().isEmpty() && mBinding.content.text.isNotEmpty()) { + mEditCommentAdapter.addListData(CommentItemEntity(label, mBinding.content.text.toString())) + } else { + mEditCommentAdapter.addListData(CommentItemEntity(label, "")) } - mEditCommentAdapter.addListData(CommentItemEntity(label, "")) mBinding.scrollView.fullScroll(NestedScrollView.FOCUS_DOWN) mBinding.content.visibility = View.GONE mBinding.rvComment.visibility = View.VISIBLE - mBinding.viewShadow.goneIf(mCommentLabelAdapter.itemCount == 0) - mBinding.rvLabel.goneIf(mCommentLabelAdapter.itemCount == 0) +// mBinding.viewShadow.goneIf(mCommentLabelAdapter.itemCount == 0) +// mBinding.rvLabel.goneIf(mCommentLabelAdapter.itemCount == 0) } mBinding.rvComment.apply { @@ -122,8 +142,8 @@ class RatingEditActivity : ToolBarActivity() { mBinding.content.visibility = View.VISIBLE mBinding.rvComment.visibility = View.GONE } - mBinding.viewShadow.visibility = View.VISIBLE - mBinding.rvLabel.visibility = View.VISIBLE +// mBinding.viewShadow.visibility = View.VISIBLE +// mBinding.rvLabel.visibility = View.VISIBLE } } @@ -303,6 +323,32 @@ class RatingEditActivity : ToolBarActivity() { } } } + override fun onResume() { + super.onResume() + mKeyboardHeightProvider?.setKeyboardHeightObserver(this) + } + + override fun onPause() { + super.onPause() + mKeyboardHeightProvider?.setKeyboardHeightObserver(null) + } + + override fun onDestroy() { + super.onDestroy() + mKeyboardHeightProvider?.close() + } + + override fun onKeyboardHeightChanged(height: Int, orientation: Int) { + val lp = mBinding.commentRuleLl.layoutParams as RelativeLayout.LayoutParams + if (height > 0) { + lp.bottomMargin = height + mOffset + } else { + mOffset = abs(height) + lp.bottomMargin = 0 + } + + mBinding.commentRuleLl.layoutParams = lp + } override fun handleBackPressed(): Boolean { diff --git a/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java b/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java index 0ffeaeb68b..02a002a4c7 100644 --- a/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java +++ b/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java @@ -150,7 +150,7 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa mMessageDetailRv.setAdapter(adapter); mMessageDetailEt.addTextChangedListener(watcher); - mMessageDetailEt.setFilters(new InputFilter[]{TextHelper.getFilter(140,"评论不能多于140字")}); + mMessageDetailEt.setFilters(new InputFilter[]{TextHelper.getFilter(140, "评论不能多于140字")}); mMessageDetailCommentSend.setEnabled(false); mMessageDetailCommentSend.setBackgroundDrawable(getResources().getDrawable(R.drawable.button_gray_style)); mMessageDetailEt.setOnFocusChangeListener((v, hasFocus) -> { @@ -298,15 +298,15 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa public void OnSendCommentListener() { PermissionHelper.checkReadPhoneStatePermissionBeforeAction(requireContext(), () -> { final String content = mMessageDetailEt.getText().toString(); - + if (content.length() == 0) { Utils.toast(getContext(), "评论内容不能为空!"); return; } - + CheckLoginUtils.checkLogin(requireContext(), "资讯文章详情-评论详情-写评论", () -> { mSendingDialog = DialogUtils.showWaitDialog(getActivity(), getString(R.string.post_dialog_hint)); - + JSONObject jsonObject = new JSONObject(); try { jsonObject.put("content", content); @@ -320,21 +320,29 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa } else if (newsId == null) { newsId = mConcernEntity.getId(); } - + PostCommentUtils.addCommentData(getContext(), newsId, jsonObject.toString(), mCommentEntity, new PostCommentUtils.PostCommentListener() { @Override public void postSuccess(JSONObject response) { mSendingDialog.dismiss(); toast("发表成功"); mMessageDetailEt.setText(""); - + try { JSONObject cacheObject = new JSONObject(); JSONObject cacheUser = new JSONObject(); JSONObject userData = new JSONObject(); + JSONObject badgeData = new JSONObject(); cacheUser.put("_id", mUserInfo.getId()); cacheUser.put("icon", mUserInfo.getIcon()); cacheUser.put("name", mUserInfo.getName()); + + if (mUserInfo.getBadge() != null) { + badgeData.put("name", mUserInfo.getBadge().getName()); + badgeData.put("icon", mUserInfo.getBadge().getIcon()); + cacheUser.put("badge", badgeData); + } + userData.put("is_comment_own", true); cacheObject.put("_id", response.getString("_id")); cacheObject.put("content", content); @@ -342,7 +350,7 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa cacheObject.put("vote", 0); cacheObject.put("user", cacheUser); cacheObject.put("me", userData); - + if (mCommentEntity != null) { JSONObject cacheParent = new JSONObject(); JSONObject cacheParentUser = new JSONObject(); @@ -352,17 +360,17 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa cacheParent.put("comment", mCommentEntity.getContent()); cacheObject.put("parent", cacheParent); } - + CommentEntity commentEntity = new Gson().fromJson(cacheObject.toString(), CommentEntity.class); if (mConcernEntity != null) { adapter.addNormalComment(commentEntity); } - + modifyNewsCommentOkhttpCache(adapter.findTheLastPriorComment(), cacheObject, newsId); } catch (JSONException e) { e.printStackTrace(); } - + if (mConcernEntity != null) { // 完成评论操作,添加评论数 adapter.addCommentCount(); @@ -374,11 +382,11 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa } else { showNoConnection(false); } - + setSoftInput(false); - + } - + @Override public void postFailed(Throwable e) { mSendingDialog.dismiss(); @@ -394,9 +402,9 @@ public class MessageDetailFragment extends NormalFragment implements OnCommentCa } }); }); - + }); - + } private void modifyNewsCommentOkhttpCache(int offset, JSONObject commentData, String id) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsViewHolder.java b/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsViewHolder.java index a16ce0713c..894802053e 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsViewHolder.java @@ -103,9 +103,11 @@ public class AskQuestionsRecommendsViewHolder extends BaseRecyclerViewHolder - + android:layout_height="match_parent" + android:layout_marginBottom="40dp"> + android:paddingBottom="12dp" + android:visibility="gone"/> - +