From 5e631652a9dfdd4dd0638dc4ff13d6e9fc9de06f Mon Sep 17 00:00:00 2001 From: 18401019693 Date: Fri, 25 Nov 2022 17:58:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=8E=A5=E5=8F=A3=E7=AC=ACer?= =?UTF-8?q?=E6=AC=A1=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/bean/EnterRoomInfoModel.java | 14 +- .../com/yunbao/common/http/PDLiveApi.java | 8 + .../common/http/live/LiveNetManager.java | 28 ++ .../yunbao/live/views/LiveRoomViewHolder.java | 20 +- .../live/views/PortraitLiveManager.java | 333 ++++++++---------- 5 files changed, 221 insertions(+), 182 deletions(-) diff --git a/common/src/main/java/com/yunbao/common/bean/EnterRoomInfoModel.java b/common/src/main/java/com/yunbao/common/bean/EnterRoomInfoModel.java index 502eb757d..87e6e14c4 100644 --- a/common/src/main/java/com/yunbao/common/bean/EnterRoomInfoModel.java +++ b/common/src/main/java/com/yunbao/common/bean/EnterRoomInfoModel.java @@ -1,8 +1,6 @@ package com.yunbao.common.bean; -import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; import java.util.List; @@ -103,6 +101,18 @@ public class EnterRoomInfoModel extends BaseModel { private String liveBg; @SerializedName("anchor_goodnum") private String anchorGoodnum; + @SerializedName("jackpot_level") + private String jackpotLevel="-1"; + + public String getJackpotLevel() { + + return jackpotLevel; + } + + public EnterRoomInfoModel setJackpotLevel(String jackpotLevel) { + this.jackpotLevel = jackpotLevel; + return this; + } public String getVotestotal() { return votestotal; diff --git a/common/src/main/java/com/yunbao/common/http/PDLiveApi.java b/common/src/main/java/com/yunbao/common/http/PDLiveApi.java index 467a7900b..22ca82f36 100644 --- a/common/src/main/java/com/yunbao/common/http/PDLiveApi.java +++ b/common/src/main/java/com/yunbao/common/http/PDLiveApi.java @@ -324,4 +324,12 @@ public interface PDLiveApi { @Query("GroupId") String GroupId, @Query("stream") String stream ); + /** + * 加入房间推送Im欢迎语 + */ + @GET("/api/public/?service=Tx.leaveRoomNew") + Observable> leaveRoomNew( + @Query("GroupId") String GroupId, + @Query("stream") String stream + ); } diff --git a/common/src/main/java/com/yunbao/common/http/live/LiveNetManager.java b/common/src/main/java/com/yunbao/common/http/live/LiveNetManager.java index 55de6fc4e..b0eb06fd9 100644 --- a/common/src/main/java/com/yunbao/common/http/live/LiveNetManager.java +++ b/common/src/main/java/com/yunbao/common/http/live/LiveNetManager.java @@ -406,4 +406,32 @@ public class LiveNetManager { } }).isDisposed(); } + + /** + * 离开直播间 + * + * @param stream + * @param liveUid + */ + public void leaveRoomNew(String stream, String liveUid,HttpCallback callback) { + API.get().pdLiveApi(mContext) + .userJoinRoomNew("g" + liveUid, stream) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer>() { + @Override + public void accept(ResponseModel stringResponseModel) throws Exception { + if (callback != null) { + callback.onSuccess(""); + } + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + if (callback != null) { + callback.onError(throwable.getMessage()); + } + } + }).isDisposed(); + } } diff --git a/live/src/main/java/com/yunbao/live/views/LiveRoomViewHolder.java b/live/src/main/java/com/yunbao/live/views/LiveRoomViewHolder.java index 4fa16ee59..67bbbc824 100644 --- a/live/src/main/java/com/yunbao/live/views/LiveRoomViewHolder.java +++ b/live/src/main/java/com/yunbao/live/views/LiveRoomViewHolder.java @@ -70,7 +70,6 @@ import com.yunbao.common.bean.LiveGiftBean; import com.yunbao.common.bean.LiveRoomActivityBanner; import com.yunbao.common.bean.LiveUserGiftBean; import com.yunbao.common.bean.MsgModel; -import com.yunbao.common.bean.NewLevelModel; import com.yunbao.common.bean.PkRankBean; import com.yunbao.common.bean.RankHourModel; import com.yunbao.common.bean.StarChallengeStatusModel; @@ -2092,8 +2091,23 @@ public class LiveRoomViewHolder extends AbsViewHolder implements View.OnClickLis } else { setHideMedalIcon(false); } + if (IMLoginManager.get(mContext).getUserInfo().anchorUserType()) { + getIsHot(); + getGuardInfo(); + } + } - getIsHot(); + private void getGuardInfo() { + LiveHttpUtil.getUserList(mLiveUid, mStream, "guard", 1, new HttpCallback() { + @Override + public void onSuccess(int code, String msg, String[] info) { + JSONObject json = JSONObject.parseObject(info[0]); + JSONArray userlist = json.getJSONArray("userlist"); + if (userlist.size() != 0) { + setGuardIcon(JSONArray.parseArray(userlist.toJSONString(), LiveUserGiftBean.class).get(0)); + } + } + }); } private void setGuardIcon(LiveUserGiftBean guard) { @@ -2460,7 +2474,7 @@ public class LiveRoomViewHolder extends AbsViewHolder implements View.OnClickLis * 刷新用户列表 */ public void refreshUserList(JSONObject obj) { - List list = GsonUtils.fromJson(obj.getString("userlist"), new TypeToken>() { + List list = GsonUtils.fromJson(obj.getString("userlist"), new TypeToken>() { }.getType()); mLiveUserAdapter.refreshList(list); } diff --git a/live/src/main/java/com/yunbao/live/views/PortraitLiveManager.java b/live/src/main/java/com/yunbao/live/views/PortraitLiveManager.java index d6c82641e..b0b18de41 100644 --- a/live/src/main/java/com/yunbao/live/views/PortraitLiveManager.java +++ b/live/src/main/java/com/yunbao/live/views/PortraitLiveManager.java @@ -21,7 +21,6 @@ import androidx.drawerlayout.widget.DrawerLayout; import androidx.viewpager.widget.PagerAdapter; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.blankj.utilcode.util.GsonUtils; import com.lzf.easyfloat.EasyFloat; @@ -267,7 +266,6 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe mLivePlayViewHolder.setCover(data.getThumb()); mLivePlayViewHolder.play(data.getPull()); mLiveRoomViewHolder.resetView(); - mLiveRoomViewHolder.clearChat(); mLiveRoomViewHolder.setAvatar(data.getAvatar()); mLiveRoomViewHolder.setAnchorLevel(data.getLevelAnchor()); mLiveRoomViewHolder.setName(data.getUserNiceName()); @@ -287,178 +285,25 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe } - private void enterRoom() { - //进入直播间IM - - - timeIndex = 0; - LiveHttpUtil.enterRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() { - @Override - public void onSuccess(int code, String msg, String[] info) { - isEnterRoom = true; - if (code == 0 && info.length > 0) { - JSONObject obj = JSON.parseObject(info[0]); - - - //连接socket - LiveHttpUtil.enterBackRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() { - @Override - public void onSuccess(int code, String msg, String[] info) { - //链接上socket以后隐藏Loading加载直播间内容 - } - }); - if (mLiveRoomViewHolder != null) { - LivePlayKsyViewHolder.setLandscape(obj.getIntValue("landscape")); - - mLiveRoomViewHolder.setLiveInfo(mLiveBean.getUid(), mLiveBean.getStream(), obj.getIntValue("userlist_time") * 4000); - mLiveRoomViewHolder.setFastMessage(greetings); - mLiveRoomViewHolder.setVotes(obj.getString("votestotal")); - //真爱排行 数量 - mLiveRoomViewHolder.setMedaRankNum(obj.getString("medalRankNum")); - isattention = obj.getIntValue("isattention"); - if (isattention == 0) { - if (countDownTimer != null) { - countDownTimer.cancel(); - timeIndex = 0; - countDownTimer = null; - setTime(); - } else { - setTime(); - } - } else { - if (countDownTimer != null) { - countDownTimer.cancel(); - countDownTimer = null; - } - } - mLiveAudienceViewHolder.setLiveInfo(mLiveBean.getUid(), mLiveBean.getStream(), mLiveBean.getAvatar(), isattention); - mLiveRoomViewHolder.setAttention(isattention); - if (obj.containsKey("lminfo")) { - JSONObject mic_data = obj.getJSONObject("lminfo"); - if (mic_data.containsKey("userlist")) { - mLiveRoomViewHolder.updataMicList(mic_data.getJSONArray("userlist")); - } - } - List list = JSON.parseArray(obj.getString("userlists"), LiveUserGiftBean.class); - mLiveRoomViewHolder.setUserList(list); - // resetUserListWidth(list); - mLiveRoomViewHolder.startRefreshUserList(); - if (mLiveType == Constants.LIVE_TYPE_TIME) {//计时收费 - mLiveRoomViewHolder.startRequestTimeCharge(); - } - } - if (leave == 1) { - if (LivePlayRyViewHolder.leave != null) { - LivePlayRyViewHolder.leave.setVisibility(View.VISIBLE); - } - } - //判断是否有连麦,要显示连麦窗口 - String linkMicUid = obj.getString("linkmic_uid"); - String linkMicPull = obj.getString("linkmic_pull"); - if (!TextUtils.isEmpty(linkMicUid) && !"0".equals(linkMicUid) && !TextUtils.isEmpty(linkMicPull)) { - if (mLiveSDK != Constants.LIVE_SDK_TX && mLiveLinkMicPresenter != null) { - mLiveLinkMicPresenter.onLinkMicPlay(linkMicUid, linkMicPull); - } - } - //判断是否有主播连麦 - pkInfo = JSON.parseObject(obj.getString("pkinfo")); - if (pkInfo != null && pkInfo.getIntValue("drpk_status") != 1) { - String pkUid = pkInfo.getString("pkuid"); - anyway = "1"; - if (!TextUtils.isEmpty(pkUid) && !"0".equals(pkUid) && anyway.equals("0")) { - if (mLiveSDK != Constants.LIVE_SDK_TX) { - String pkPull = pkInfo.getString("pkpull"); - if (!TextUtils.isEmpty(pkPull) && mLiveLinkMicAnchorPresenter != null) { - mLiveLinkMicAnchorPresenter.onLinkMicAnchorPlayUrl(pkUid, pkPull); - } - } else { - if (mLivePlayViewHolder instanceof LivePlayTxViewHolder) { - ((LivePlayTxViewHolder) mLivePlayViewHolder).setAnchorLinkMic(true, 0); - } - } - } - - if (obj.getString("isconnection") != null && obj.getString("isconnection").equals("1")) { - - LivePlayRyViewHolder.setViewUP(1); - - } - if (pkInfo.getIntValue("ifpk") == 1 && pkInfo.getString("end_pk_time").equals("0")) {//pk开始了 - - LivePlayRyViewHolder.setViewUP(2); - - //pk排名数据 - LivePKUserListBean livePKUserListBean = JSON.parseObject(pkInfo.getString("pk_top_users"), LivePKUserListBean.class); - if (mLiveRoomViewHolder != null) { - mLiveRoomViewHolder.setOtherInfo(pkInfo.getString("pkuid"), pkInfo.getString("pkuimg"), pkInfo.getString("pkuname")); - } - mLiveRyLinkMicPkPresenter.onEnterRoomPkStart(pkUid, pkInfo.getLongValue("pk_gift_liveuid"), pkInfo.getLongValue("pk_gift_pkuid"), pkInfo.getIntValue("pk_time"), livePKUserListBean); - } else if (!pkInfo.getString("end_pk_time").equals("0")) { - - LivePlayRyViewHolder.setViewUP(3); - - //pk排名数据 - LivePKUserListBean livePKUserListBean = JSON.parseObject(pkInfo.getString("pk_top_users"), LivePKUserListBean.class); - mLiveRyLinkMicPkPresenter.onEnterRoomCFStart(pkUid, pkInfo.getLongValue("pk_gift_liveuid"), pkInfo.getLongValue("pk_gift_pkuid"), pkInfo.getIntValue("end_pk_time"), livePKUserListBean); - } - //多人PK - } else if (pkInfo != null && pkInfo.getIntValue("drpk_status") == 1) { - - LivePlayRyViewHolder.setViewUP(4); - - mLiveRoomViewHolder.UpPkBar(pkInfo.getJSONArray("userlist"), mLiveBean.getUid(), pkInfo.getIntValue("drpk_time")); - } - - //守护相关 - mLiveGuardInfo = new LiveGuardInfo(); - int guardNum = obj.getIntValue("guard_nums"); - fansNum = obj.getIntValue("count_fans"); - is_fans = obj.getString("is_fans") + ""; - mLiveGuardInfo.setGuardNum(guardNum); - JSONObject guardObj = obj.getJSONObject("guard"); - if (guardObj != null) { - mLiveGuardInfo.setMyGuardType(guardObj.getIntValue("type")); - mLiveGuardInfo.setMyGuardEndTime(guardObj.getString("endtime")); - } - Bus.get().post(new LiveAudienceEvent() - .setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS) - .setParametersModel(openParametersModel.setmLiveGuardInfo(mLiveGuardInfo) - .setFansNum(fansNum) - .setIs_fans(is_fans))); - if (mLiveRoomViewHolder != null) { - mLiveRoomViewHolder.setGuardNum(guardNum); - mLiveRoomViewHolder.setFansNum(fansNum); - //红包相关 - mLiveRoomViewHolder.setRedPackBtnVisible(obj.getIntValue("isred") == 1); - } - //奖池等级 - int giftPrizePoolLevel = obj.getIntValue("jackpot_level"); - if (giftPrizePoolLevel >= 0) { - if (mLiveRoomViewHolder != null) { - mLiveRoomViewHolder.showPrizePoolLevel(String.valueOf(giftPrizePoolLevel)); - } - } - } - } - }); - } - /** * 新进入房间接口 */ private void enterRoomNew() { + timeIndex = 0; LiveNetManager.get(mContext) .enterRoomNew(mLiveBean.getStream(), mLiveBean.getUid(), mLiveBean.getCity(), new com.yunbao.common.http.base.HttpCallback() { @Override public void onSuccess(EnterRoomNewModel data) { + mLiveRoomViewHolder.clearChat(); + isEnterRoom = true; + //加入房间发送Im消息 + LiveNetManager.get(mContext).userJoinRoomNew(mLiveBean.getStream(), mLiveBean.getUid()); //小时榜 mLiveRoomViewHolder.initHourRank(data.getRankHour()); //守护 mLiveRoomViewHolder.setGuardIcon(data.getGuardUserAvatar()); //在线列表 mLiveRoomViewHolder.setUserList(data.getEnterRoomInfo().getUserlists()); - //设置直播信息 - mLiveRoomViewHolder.setLiveInfo(mLiveBean.getUid(), mLiveBean.getStream(), Integer.parseInt(data.getEnterRoomInfo().getUserlistTime()) * 4000); List bannerBeans = new ArrayList<>(); //心愿单 if (data.getWishList().getWishList().size() > 0) { @@ -513,8 +358,132 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe .setmChatLevel(mChatLevel) .setmDanMuLevel(mDanMuLevel) .setLiveBg(liveBg))); - //加入房间发送Im消息 - LiveNetManager.get(mContext).userJoinRoomNew(mLiveBean.getStream(), mLiveBean.getUid()); + //数据设置 + if (mLiveRoomViewHolder != null) { + LivePlayKsyViewHolder.setLandscape(Integer.parseInt(data.getEnterRoomInfo().getLandscape())); + mLiveRoomViewHolder.setLiveInfo(mLiveBean.getUid(), mLiveBean.getStream(), Integer.parseInt(data.getEnterRoomInfo().getUserlistTime()) * 4000); + mLiveRoomViewHolder.setFastMessage(greetings); + mLiveRoomViewHolder.setVotes(data.getEnterRoomInfo().getVotestotal()); + //真爱排行 数量 + mLiveRoomViewHolder.setMedaRankNum(data.getEnterRoomInfo().getMedalRankNum()); + isattention = Integer.parseInt(data.getEnterRoomInfo().getIsattention()); + if (isattention == 0) { + if (countDownTimer != null) { + countDownTimer.cancel(); + timeIndex = 0; + countDownTimer = null; + setTime(); + } else { + setTime(); + } + } else { + if (countDownTimer != null) { + countDownTimer.cancel(); + countDownTimer = null; + } + } + mLiveAudienceViewHolder.setLiveInfo(mLiveBean.getUid(), mLiveBean.getStream(), mLiveBean.getAvatar(), isattention); + mLiveRoomViewHolder.setAttention(isattention); + List list = data.getEnterRoomInfo().getUserlists(); + mLiveRoomViewHolder.setUserList(list); + mLiveRoomViewHolder.startRefreshUserList(); + if (mLiveType == Constants.LIVE_TYPE_TIME) {//计时收费 + mLiveRoomViewHolder.startRequestTimeCharge(); + } + } + + if (leave == 1) { + if (LivePlayRyViewHolder.leave != null) { + LivePlayRyViewHolder.leave.setVisibility(View.VISIBLE); + } + } + //判断是否有连麦,要显示连麦窗口 + String linkMicUid = data.getEnterRoomInfo().getLinkmicUid(); + String linkMicPull = data.getEnterRoomInfo().getLinkmicPull(); + if (!TextUtils.isEmpty(linkMicUid) && !"0".equals(linkMicUid) && !TextUtils.isEmpty(linkMicPull)) { + if (mLiveSDK != Constants.LIVE_SDK_TX && mLiveLinkMicPresenter != null) { + mLiveLinkMicPresenter.onLinkMicPlay(linkMicUid, linkMicPull); + } + } + + //判断是否有主播连麦 + pkInfo = JSON.parseObject(GsonUtils.toJson(data.getEnterRoomInfo().getPkinfo())); + if (pkInfo != null && pkInfo.getIntValue("drpk_status") != 1) { + String pkUid = pkInfo.getString("pkuid"); + anyway = "1"; + if (!TextUtils.isEmpty(pkUid) && !"0".equals(pkUid) && anyway.equals("0")) { + if (mLiveSDK != Constants.LIVE_SDK_TX) { + String pkPull = pkInfo.getString("pkpull"); + if (!TextUtils.isEmpty(pkPull) && mLiveLinkMicAnchorPresenter != null) { + mLiveLinkMicAnchorPresenter.onLinkMicAnchorPlayUrl(pkUid, pkPull); + } + } else { + if (mLivePlayViewHolder instanceof LivePlayTxViewHolder) { + ((LivePlayTxViewHolder) mLivePlayViewHolder).setAnchorLinkMic(true, 0); + } + } + } + + if (data.getEnterRoomInfo().getIsattention() != null && data.getEnterRoomInfo().getIsattention().equals("1")) { + + LivePlayRyViewHolder.setViewUP(1); + + } + if (pkInfo.getIntValue("ifpk") == 1 && pkInfo.getString("end_pk_time").equals("0")) {//pk开始了 + + LivePlayRyViewHolder.setViewUP(2); + + //pk排名数据 + LivePKUserListBean livePKUserListBean = JSON.parseObject(pkInfo.getString("pk_top_users"), LivePKUserListBean.class); + if (mLiveRoomViewHolder != null) { + mLiveRoomViewHolder.setOtherInfo(pkInfo.getString("pkuid"), pkInfo.getString("pkuimg"), pkInfo.getString("pkuname")); + } + mLiveRyLinkMicPkPresenter.onEnterRoomPkStart(pkUid, pkInfo.getLongValue("pk_gift_liveuid"), pkInfo.getLongValue("pk_gift_pkuid"), pkInfo.getIntValue("pk_time"), livePKUserListBean); + } else if (!pkInfo.getString("end_pk_time").equals("0")) { + + LivePlayRyViewHolder.setViewUP(3); + + //pk排名数据 + LivePKUserListBean livePKUserListBean = JSON.parseObject(pkInfo.getString("pk_top_users"), LivePKUserListBean.class); + mLiveRyLinkMicPkPresenter.onEnterRoomCFStart(pkUid, pkInfo.getLongValue("pk_gift_liveuid"), pkInfo.getLongValue("pk_gift_pkuid"), pkInfo.getIntValue("end_pk_time"), livePKUserListBean); + } + //多人PK + } else if (pkInfo != null && pkInfo.getIntValue("drpk_status") == 1) { + + LivePlayRyViewHolder.setViewUP(4); + + mLiveRoomViewHolder.UpPkBar(pkInfo.getJSONArray("userlist"), mLiveBean.getUid(), pkInfo.getIntValue("drpk_time")); + } + //守护相关 + mLiveGuardInfo = new LiveGuardInfo(); + int guardNum = Integer.parseInt(data.getEnterRoomInfo().getGuardNums()); + fansNum = Integer.parseInt(data.getEnterRoomInfo().getCountFans()); + is_fans = data.getEnterRoomInfo().getIsFans(); + mLiveGuardInfo.setGuardNum(guardNum); + JSONObject guardObj = JSONObject.parseObject(GsonUtils.toJson(data.getEnterRoomInfo().getGuard())); + if (guardObj != null) { + mLiveGuardInfo.setMyGuardType(guardObj.getIntValue("type")); + mLiveGuardInfo.setMyGuardEndTime(guardObj.getString("endtime")); + } + Bus.get().post(new LiveAudienceEvent() + .setType(LiveAudienceEvent.LiveAudienceType.OPEN_PARAMETERS) + .setParametersModel(openParametersModel.setmLiveGuardInfo(mLiveGuardInfo) + .setFansNum(fansNum) + .setIs_fans(is_fans))); + if (mLiveRoomViewHolder != null) { + mLiveRoomViewHolder.setGuardNum(guardNum); + mLiveRoomViewHolder.setFansNum(fansNum); + //红包相关 + mLiveRoomViewHolder.setRedPackBtnVisible(Integer.parseInt(data.getEnterRoomInfo().getIsred()) == 1); + } + + //奖池等级 + int giftPrizePoolLevel = Integer.parseInt(data.getEnterRoomInfo().getJackpotLevel()); + if (giftPrizePoolLevel >= 0) { + if (mLiveRoomViewHolder != null) { + mLiveRoomViewHolder.showPrizePoolLevel(String.valueOf(giftPrizePoolLevel)); + } + } } @Override @@ -1440,16 +1409,21 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe @Override public void onSuccess() { Log.i("tx", "退出成功"); - //连接socket - LiveHttpUtil.qBackRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() { - @Override - public void onSuccess(int code, String msg, String[] info) { - if (isQuitF) { - onRemove(true); - } + LiveNetManager.get(mContext) + .leaveRoomNew(mLiveBean.getStream(), mLiveBean.getUid(), new com.yunbao.common.http.base.HttpCallback() { + @Override + public void onSuccess(String data) { + if (isQuitF) { + onRemove(true); + } + } + + @Override + public void onError(String error) { + + } + }); - } - }); } @Override @@ -1464,13 +1438,18 @@ public class PortraitLiveManager implements LivePlayListener, SocketMessageListe public void onSuccess() { Log.i("tx", "退出成功" + mLiveBean.getUid()); - //连接socket - LiveHttpUtil.qBackRoom(mLiveBean.getUid(), mLiveBean.getStream(), new HttpCallback() { - @Override - public void onSuccess(int code, String msg, String[] info) { + LiveNetManager.get(mContext) + .leaveRoomNew(mLiveBean.getStream(), mLiveBean.getUid(), new com.yunbao.common.http.base.HttpCallback() { + @Override + public void onSuccess(String data) { - } - }); + } + + @Override + public void onError(String error) { + + } + }); } @Override