package com.gh.gamecenter.message; import android.app.Activity; import android.app.Dialog; import android.content.Intent; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import com.gh.common.constant.Config; import com.gh.common.util.CheckLoginUtils; import com.gh.common.util.DialogUtils; import com.gh.common.util.EntranceUtils; import com.gh.common.util.ErrorHelper; import com.gh.common.util.PostCommentUtils; import com.gh.common.util.TimestampUtils; import com.gh.gamecenter.R; import com.gh.gamecenter.adapter.MessageDetailAdapter; import com.gh.gamecenter.adapter.OnCommentCallBackListener; import com.gh.gamecenter.entity.CommentEntity; import com.gh.gamecenter.entity.CommentnumEntity; import com.gh.gamecenter.entity.ConcernEntity; import com.gh.gamecenter.entity.UserInfoEntity; import com.gh.gamecenter.entity.ViewsEntity; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.manager.CommentManager; import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.normal.NormalFragment; import com.gh.gamecenter.retrofit.OkHttpCache; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.google.gson.Gson; import com.halo.assistant.HaloApp; import com.lightgame.listeners.OnBackPressedListener; import com.lightgame.utils.Util_System_Keyboard; import com.lightgame.utils.Utils; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.List; import butterknife.BindView; import butterknife.OnClick; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import retrofit2.HttpException; import static com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG; /** * Created by CsHeng on 18/12/2017. * 消息详情界面--评论详情--对话详情 */ public class MessageDetailFragment extends NormalFragment implements OnCommentCallBackListener, OnBackPressedListener { public static final int REQUEST_UPDATE_COMMENT = 9; // 刷新文章web页面评论数 @BindView(R.id.message_detail_rv) RecyclerView mMessageDetailRv; @BindView(R.id.comment_send_btn) TextView mMessageDetailCommentSend; @BindView(R.id.comment_et) EditText mMessageDetailEt; @BindView(R.id.reuse_no_connection) LinearLayout mNoConnection; private LinearLayoutManager mLayoutManager; private MessageDetailAdapter adapter; private Dialog mSendingDialog; private ConcernEntity mConcernEntity; private CommentEntity mCommentEntity; // 回复评论的实体 用完马上清空 private UserInfoEntity mUserInfo; private String newsId; private int commentNum = -1; //区分来源 -1:资讯关注列表 !=-1 :新闻详情 private TextWatcher watcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (s.toString().trim().length() > 0) { mMessageDetailCommentSend.setEnabled(true); mMessageDetailCommentSend.setBackgroundDrawable(getResources().getDrawable(R.drawable.button_normal_style)); if (s.length() > 140) { mMessageDetailEt.setText(""); String newText = s.toString().substring(0, 140); mMessageDetailEt.setText(newText); mMessageDetailEt.setSelection(mMessageDetailEt.getText().length()); Utils.toast(getContext(), "评论不能多于140字"); } } else { mMessageDetailCommentSend.setEnabled(false); mMessageDetailCommentSend.setBackgroundDrawable(getResources().getDrawable(R.drawable.button_gray_style)); } } @Override public void afterTextChanged(Editable s) { } }; @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(CommentEntity.TAG, adapter.getConcernEntity()); } @Override protected int getLayoutId() { return R.layout.fragment_message_detail; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle args = getArguments(); // mConcernEntity = args.getParcelable(ConcernEntity.TAG); mConcernEntity = (ConcernEntity) HaloApp.get(ConcernEntity.TAG, true); mCommentEntity = args.getParcelable(CommentEntity.TAG); newsId = args.getString(EntranceUtils.KEY_NEWSID); commentNum = args.getInt("commentNum", -1); //复用问题 mConcernEntity对应的文章有可能和跳转之前的文章不一致 if (mConcernEntity != null && newsId != null && !newsId.equals(mConcernEntity.getId())) { mConcernEntity = null; } setNavigationTitle(getString(R.string.title_message_detail)); adapter = new MessageDetailAdapter(getActivity(), this, mMessageDetailRv, mConcernEntity, mEntrance); mLayoutManager = new LinearLayoutManager(getContext()); mMessageDetailRv.setLayoutManager(mLayoutManager); mMessageDetailRv.setAdapter(adapter); mMessageDetailEt.addTextChangedListener(watcher); mMessageDetailCommentSend.setEnabled(false); mMessageDetailCommentSend.setBackgroundDrawable(getResources().getDrawable(R.drawable.button_gray_style)); mMessageDetailEt.setOnFocusChangeListener((v, hasFocus) -> { if (hasFocus) { mMessageDetailEt.setHintTextColor(ContextCompat.getColor(getContext(), R.color.hint)); } else { mMessageDetailEt.setHintTextColor(ContextCompat.getColor(getContext(), R.color.theme)); } }); mMessageDetailRv.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE && !adapter.isOver() && !adapter.isLoading() && mConcernEntity != null && mLayoutManager.findLastVisibleItemPosition() == adapter.getItemCount() - 1) { int offset = adapter.getItemCount() - adapter.getHotCommentListSize() - 3; if (offset >= 10) { // 防止自动上滑时触发 adapter.addNormalComment(); } } } }); mUserInfo = UserManager.getInstance().getUserInfoEntity(); if (newsId != null && mConcernEntity == null) { getConcernDigest(); } if (args.getBoolean("openSoftInput", false)) {//新闻详情的发表评论 setSoftInput(true); } } public void getCommentNum() { RetrofitManager.getInstance(getContext()).getApi() .getNewsCommentnum(newsId, Utils.getTime(getContext())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new com.gh.gamecenter.retrofit.Response>() { @Override public void onResponse(List response) { super.onResponse(response); if (response.size() > 0) { if (!TextUtils.isEmpty(mConcernEntity.getId())) { commentNum = response.get(0).getNum(); mConcernEntity.setCommentnum(commentNum); adapter.notifyItemChanged(0); } } } }); } private void getConcernDigest() { RetrofitManager.getInstance(getContext()).getApi().getNewsRichDigest(newsId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(ConcernEntity response) { mConcernEntity = response; if (commentNum == -1) { getCommentNum(); } else { mConcernEntity.setCommentnum(commentNum); } adapter.addConcernEntity(mConcernEntity); adapter.notifyDataSetChanged(); adapter.addHotComment(); getNewsViews(); if (commentNum == 0) { setSoftInput(true); } } @Override public void onFailure(HttpException e) { showNoConnection(true); } }); } private void getNewsViews() { RetrofitManager.getInstance(getContext()).getData() .getNewsViews(newsId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response>() { @Override public void onResponse(List viewsEntities) { if (viewsEntities.size() > 0) { mConcernEntity.setViews(viewsEntities.get(0).getViews()); adapter.notifyItemChanged(0); } } }); } @OnClick({R.id.reuse_no_connection}) public void OnViewClick(View view) { if (view.getId() == R.id.reuse_no_connection) { if (newsId != null && mConcernEntity == null) { showNoConnection(false); } } } //软键盘控制 private void setSoftInput(boolean isShow) { if (isShow) { CheckLoginUtils.checkLogin(getContext(), () -> { Util_System_Keyboard.showSoftKeyboard(getContext(), mMessageDetailEt); mMessageDetailEt.setFocusable(true); mMessageDetailEt.setFocusableInTouchMode(true); mMessageDetailEt.requestFocus(); if (mCommentEntity != null && mCommentEntity.getUser() != null) { mMessageDetailEt.setHint(getString(R.string.comment_repty_hint, mCommentEntity.getUser().getName())); } else { mMessageDetailEt.setHint(getString(R.string.message_detail_comment_hint)); } }); } else { Util_System_Keyboard.hideSoftKeyboard(getActivity()); if (mCommentEntity != null) { mCommentEntity = null; // 清空当前评论实体 mMessageDetailEt.setHint(getString(R.string.message_detail_comment_hint)); mMessageDetailEt.setText(""); } } } @OnClick(R.id.comment_send_btn) public void OnSendCommentListener() { 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); } catch (JSONException e) { e.printStackTrace(); } if (newsId == null && mConcernEntity == null || newsId == null && mConcernEntity.getId() == null) { Utils.toast(getContext(), "评论异常 id null"); mSendingDialog.cancel(); return; } 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(); cacheUser.put("_id", mUserInfo.getId()); cacheUser.put("icon", mUserInfo.getIcon()); cacheUser.put("name", mUserInfo.getName()); userData.put("is_comment_own", true); cacheObject.put("_id", response.getString("_id")); cacheObject.put("content", content); cacheObject.put("time", System.currentTimeMillis() / 1000); cacheObject.put("vote", 0); cacheObject.put("user", cacheUser); cacheObject.put("me", userData); if (mCommentEntity != null) { JSONObject cacheParent = new JSONObject(); JSONObject cacheParentUser = new JSONObject(); cacheParentUser.put("_id", mCommentEntity.getId()); cacheParentUser.put("name", mCommentEntity.getUser().getName()); cacheParent.put("user", cacheParentUser); 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(); //修改评论缓存 CommentManager.updateOkhttpCacheForId(getContext(), newsId); CommentManager.updateOkhttpCache(getContext(), newsId); adapter.notifyItemInserted(adapter.getHotCommentListSize() + 2); adapter.notifyItemChanged(adapter.getItemCount() - 1); //刷新脚布局高度 } else { showNoConnection(false); } setSoftInput(false); } @Override public void postFailed(Throwable e) { mSendingDialog.dismiss(); String errorString = null; if (e instanceof HttpException) { try { errorString = ((HttpException) e).response().errorBody().string(); } catch (Exception e1) { e1.printStackTrace(); } } ErrorHelper.INSTANCE.handleError(requireContext(), errorString, false); } }); }); } private void modifyNewsCommentOkhttpCache(int offset, JSONObject commentData, String id) { String key = TimestampUtils.addTimestamp(Config.COMMENT_HOST + "article/" + id + "/comment?limit=10&offset=" + offset); byte[] data = OkHttpCache.getCache(getContext(), key); if (data != null) { try { JSONArray jsonArray = new JSONArray(new String(data)); JSONArray newComment = new JSONArray(); newComment.put(commentData); for (int i = 0, size = jsonArray.length() > 9 ? 9 : jsonArray.length(); i < size; i++) { newComment.put(jsonArray.get(i)); } OkHttpCache.updateCache(getContext(), key, newComment.toString().getBytes()); if (jsonArray.length() == 10) { modifyNewsCommentOkhttpCache(offset + 10, jsonArray.getJSONObject(9), id); } } catch (JSONException e) { e.printStackTrace(); } } } private void showNoConnection(boolean isShow) { if (isShow) { mNoConnection.setVisibility(View.VISIBLE); mMessageDetailRv.setVisibility(View.GONE); } else { mNoConnection.setVisibility(View.GONE); mMessageDetailRv.setVisibility(View.VISIBLE); if (newsId != null) { getConcernDigest(); } } } // 登录事件 @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBReuse reuse) { if (reuse.getType().equals(LOGIN_TAG)) { // 登入 mUserInfo = UserManager.getInstance().getUserInfoEntity(); } } @Override public void onCommentCallback(CommentEntity entity) { mCommentEntity = entity; setSoftInput(true); } @Override public boolean onHandleBackPressed() { if (commentNum != -1 && adapter.getConcernEntity() != null && commentNum != adapter.getConcernEntity().getCommentnum()) { Intent intent = new Intent(); intent.putExtra("commentNum", adapter.getConcernEntity().getCommentnum()); if (getActivity() != null) { getActivity().setResult(Activity.RESULT_OK, intent); getActivity().finish(); } return true; } return false; } }