From d0e49b8c045e09e96cc875b27033b4bfcf07438f Mon Sep 17 00:00:00 2001 From: wjc <1243177876@qq.com> Date: 星期二, 29 四月 2025 20:50:37 +0800 Subject: [PATCH] 2025年04月29日20:50:35 --- app/src/main/java/com/hdl/photovoltaic/ui/message/MessageFragment.java | 309 +++++++++++++++++++++++++++++++++++---------------- 1 files changed, 211 insertions(+), 98 deletions(-) diff --git a/app/src/main/java/com/hdl/photovoltaic/ui/message/MessageFragment.java b/app/src/main/java/com/hdl/photovoltaic/ui/message/MessageFragment.java index a9457f6..2f63d48 100644 --- a/app/src/main/java/com/hdl/photovoltaic/ui/message/MessageFragment.java +++ b/app/src/main/java/com/hdl/photovoltaic/ui/message/MessageFragment.java @@ -1,7 +1,9 @@ package com.hdl.photovoltaic.ui.message; import android.annotation.SuppressLint; +import android.content.DialogInterface; import android.content.Intent; +import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.TextView; @@ -12,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import com.google.gson.Gson; import com.hdl.linkpm.sdk.core.exception.HDLException; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.base.CustomBaseFragment; @@ -28,7 +31,10 @@ import com.hdl.photovoltaic.ui.adapter.MessageAdapter; import com.hdl.photovoltaic.ui.bean.MessageBean; import com.hdl.photovoltaic.ui.bean.UnCountBean; +import com.hdl.photovoltaic.widget.BTypeTitleListDialog; import com.hdl.photovoltaic.widget.TypeTitleListDialog; +import com.hdl.photovoltaic.widget.refreshlayout.BGARefreshLayout; +import com.hdl.photovoltaic.widget.refreshlayout.HDLRefreshViewHolder; import com.hdl.sdk.link.core.bean.eventbus.BaseEventBus; import org.greenrobot.eventbus.EventBus; @@ -51,10 +57,13 @@ private boolean isAlarmDeviceClick = true;//true琛ㄧず鍛婅璁惧琚�変腑,鍒檉alse琛ㄧず鎶ヨ璁板綍琚�変腑 private final List<MessageBean> mList = new ArrayList<>(); + + private boolean isRefreshTotalCount = true; + private int mTotalCount = 0; //鎬绘潯鏁� private int mCurrentPage = 0; // 褰撳墠椤电爜 private int mCurrentTotal = 0; // 鎬婚〉鐮� - private String mDeviceTypeFilterKye = FilterType.deviceType;//杩囨护绫诲瀷 deviceType锛圛NV 锛氶�嗗彉鍣紱BMS 锛欱MS鎺у埗鐩掞紱BATTERY 锛氱數姹犲崟鍏冿級 - private String mDeviceTypeFilterValue = FilterType.all;//杩囨护绫诲瀷鍊� deviceType锛圛NV 锛氶�嗗彉鍣紱BMS 锛欱MS鎺у埗鐩掞紱BATTERY 锛氱數姹犲崟鍏冿級 + private String mDeviceTypeFilterKye = FilterType.deviceType;//杩囨护绫诲瀷 deviceType锛圛NV 锛氶�嗗彉鍣紱BMS 锛欱MS鎺у埗鐩掞紱BATTERY 锛氱數姹犲崟鍏冿紱"LOAD_CENTRE"锛氳礋杞芥帶鍒朵腑蹇冿級 + private String mDeviceTypeFilterValue = FilterType.all;//杩囨护绫诲瀷鍊� deviceType锛圛NV 锛氶�嗗彉鍣紱BMS 锛欱MS鎺у埗鐩掞紱BATTERY 锛氱數姹犲崟鍏冿紱"LOAD_CENTRE"锛氳礋杞芥帶鍒朵腑蹇� private String mTypeFilterKye = FilterType.all;//杩囨护绫诲瀷 type锛團AULT 锛氭晠闅滐紱 WARN 锛氬憡璀︼紱 EVENT 锛氫簨浠�(鎻愮ず)锛夛紱 private String mTypeFilterValue = FilterType.all;//杩囨护绫诲瀷鍊� type锛團AULT 锛氭晠闅滐紱 WARN 锛氬憡璀︼紱 EVENT 锛氫簨浠�(鎻愮ず)锛夛紱 @@ -92,10 +101,20 @@ if (isAlarmDeviceClick) { return; } + mDeviceTypeFilterKye = FilterType.deviceType; + mDeviceTypeFilterValue = FilterType.all; + mTypeFilterKye = FilterType.all; + mTypeFilterValue = FilterType.all; + mTimeTypeFilterKye = FilterType.all; + mTimeTypeFilterValue = FilterType.all; + viewBinding.allDeviceTitleTv.setText(getString(R.string.alarm_all_device)); + viewBinding.allGradeTitleTv.setText(getString(R.string.alarm_all_grade)); + viewBinding.allTimeTitleTv.setText(getString(R.string.alarm_all_time)); isAlarmDeviceClick = true; - viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text20Style); - viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text16Style); - viewBinding.allClearTv.setVisibility(View.VISIBLE); + isRefreshTotalCount = true; + viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text18Style); + viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text14Style); + viewBinding.allClearIv.setVisibility(View.VISIBLE); loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); } }); @@ -106,10 +125,20 @@ if (!isAlarmDeviceClick) { return; } + mDeviceTypeFilterKye = FilterType.deviceType; + mDeviceTypeFilterValue = FilterType.all; + mTypeFilterKye = FilterType.all; + mTypeFilterValue = FilterType.all; + mTimeTypeFilterKye = FilterType.all; + mTimeTypeFilterValue = FilterType.all; + viewBinding.allDeviceTitleTv.setText(getString(R.string.alarm_all_device)); + viewBinding.allGradeTitleTv.setText(getString(R.string.alarm_all_grade)); + viewBinding.allTimeTitleTv.setText(getString(R.string.alarm_all_time)); isAlarmDeviceClick = false; - viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text16Style); - viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text20Style); - viewBinding.allClearTv.setVisibility(View.GONE); + isRefreshTotalCount = true; + viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text14Style); + viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text18Style); + viewBinding.allClearIv.setVisibility(View.GONE); loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); } }); @@ -117,27 +146,34 @@ viewBinding.messageSearchCl.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + String messageStateType; + if (isAlarmDeviceClick) { + messageStateType = MessageStateType.untreated; + } else { + messageStateType = MessageStateType.processed; + } Intent intent = new Intent(); + intent.putExtra("MessageStateType", messageStateType); intent.setClass(_mActivity, SearchMessageActivity.class); startActivity(intent); } }); //娓呯┖鎵�鏈夋湭璇绘寜閽� - viewBinding.allClearTv.setOnClickListener(new View.OnClickListener() { + viewBinding.allClearIv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - showLoading(); +// showLoading(); HdlMessageLogic.getInstance().messageAllRead("", new CloudCallBeak<Boolean>() { @Override public void onSuccess(Boolean obj) { - hideLoading(); +// hideLoading(); loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); } @Override public void onFailure(HDLException e) { - hideLoading(); +// hideLoading(); HdlThreadLogic.toast(_mActivity, e); } }); @@ -151,21 +187,7 @@ viewBinding.allDeviceTitleIv.setBackgroundResource(R.drawable.up); viewBinding.allGradeTitleIv.setBackgroundResource(R.drawable.down); viewBinding.allTimeTitleIv.setBackgroundResource(R.drawable.down); - List<String> stringList = getTypeList(FilterType.deviceType); - TypeTitleListDialog typeTitleListDialog = new TypeTitleListDialog(_mActivity, stringList); - typeTitleListDialog.show(); - typeTitleListDialog.setOnListener(new TypeTitleListDialog.OnClickListener() { - @Override - public void onClick(int position, String title) { - - viewBinding.allDeviceTitleTv.setText(title); - mDeviceTypeFilterKye = FilterType.deviceType; - mDeviceTypeFilterValue = findFilterValueString(title); - loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); - - } - }); - + setTypeTitleListDialog(viewBinding.allDeviceTitleTv, FilterType.deviceType, getTypeList(FilterType.deviceType)); } }); @@ -176,18 +198,8 @@ viewBinding.allDeviceTitleIv.setBackgroundResource(R.drawable.down); viewBinding.allGradeTitleIv.setBackgroundResource(R.drawable.up); viewBinding.allTimeTitleIv.setBackgroundResource(R.drawable.down); - List<String> stringList = getTypeList(FilterType.type); - TypeTitleListDialog typeTitleListDialog = new TypeTitleListDialog(_mActivity, stringList); - typeTitleListDialog.show(); - typeTitleListDialog.setOnListener(new TypeTitleListDialog.OnClickListener() { - @Override - public void onClick(int position, String title) { - viewBinding.allGradeTitleTv.setText(title); - mTypeFilterKye = FilterType.type; - mTypeFilterValue = findFilterValueString(title); - loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); - } - }); + setTypeTitleListDialog(viewBinding.allGradeTitleTv, FilterType.type, getTypeList(FilterType.type)); + } }); //鍏ㄩ儴鏃堕棿(褰撳ぉ銆佽繎3澶┿�佽繎7澶┿�佽繎30澶�)鎸夐挳 @@ -197,50 +209,7 @@ viewBinding.allDeviceTitleIv.setBackgroundResource(R.drawable.down); viewBinding.allGradeTitleIv.setBackgroundResource(R.drawable.down); viewBinding.allTimeTitleIv.setBackgroundResource(R.drawable.up); - List<String> stringList = getTypeList(FilterType.timeType); - TypeTitleListDialog typeTitleListDialog = new TypeTitleListDialog(_mActivity, stringList); - typeTitleListDialog.show(); - typeTitleListDialog.setOnListener(new TypeTitleListDialog.OnClickListener() { - @Override - public void onClick(int position, String title) { - viewBinding.allTimeTitleTv.setText(title); - mTimeTypeFilterKye = FilterType.timeType; - mTimeTypeFilterValue = findFilterValueString(title); - loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); - } - }); - } - }); - - //涓嬫媺鎸夐挳 - viewBinding.messageSrl.setColorSchemeResources(R.color.text_FF245EC3); - viewBinding.messageSrl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - viewBinding.messageSrl.setRefreshing(false); - loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); - } - }); - //涓婃媺鎸夐挳 - viewBinding.messageRcv.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { -// super.onScrolled(recyclerView, dx, dy); - - LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); - if (layoutManager == null) { - return; - } - int visibleItemCount = layoutManager.getChildCount(); - int totalItemCount = layoutManager.getItemCount(); - int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition(); - if (visibleItemCount > 0 && visibleItemCount + firstVisibleItemPosition == totalItemCount) { - if (!isLoadingMore) { - // 婊戝姩鍒颁簡搴曢儴锛屾墽琛岀浉搴旂殑鎿嶄綔 - HdlLogLogic.print("--->婊戝姩鍒颁簡搴曢儴"); - loadNextPageMessageList(false, ++mCurrentPage, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, false); - } - } + setTypeTitleListDialog(viewBinding.allTimeTitleTv, FilterType.timeType, getTypeList(FilterType.timeType)); } }); if (mMessageAdapter != null) { @@ -248,7 +217,7 @@ @Override public void onClick(int position, MessageBean messageBean) { Intent intent = new Intent(); - intent.putExtra("msgId", messageBean.getMsgId().toString()); + intent.putExtra("messageBean", new Gson().toJson(messageBean)); intent.setClass(_mActivity, MessageInfoActivity.class); startActivity(intent); } @@ -257,20 +226,132 @@ } } + /** + * 绫诲瀷绛涢�� + * + * @param textView 缁勪欢鏄剧ず + * @param filterType 杩囨护绫诲瀷 + * @param stringList 杩囨护绫诲瀷鍊艰〃 + */ + private void setTypeTitleListDialog(TextView textView, String filterType, List<String> stringList) { + BTypeTitleListDialog typeTitleListDialog = new BTypeTitleListDialog(_mActivity, stringList, textView.getText().toString()); + typeTitleListDialog.show(); + typeTitleListDialog.setOnListener(new BTypeTitleListDialog.OnClickListener() { + @Override + public void onClick(int position, String title) { + textView.setText(title); + switch (filterType) { + case FilterType.deviceType: { + mDeviceTypeFilterKye = filterType; + mDeviceTypeFilterValue = findFilterValueString(title); + } + break; + case FilterType.type: { + mTypeFilterKye = filterType; + mTypeFilterValue = findFilterValueString(title); + } + break; + case FilterType.timeType: { + mTimeTypeFilterKye = filterType; + mTimeTypeFilterValue = findFilterValueString(title); + } + break; + } + loadNextPageMessageList(true, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); + } + }); + typeTitleListDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + viewBinding.allDeviceTitleIv.setBackgroundResource(R.drawable.down); + viewBinding.allGradeTitleIv.setBackgroundResource(R.drawable.down); + viewBinding.allTimeTitleIv.setBackgroundResource(R.drawable.down); + } + }); + } + private void initView() { if (isAlarmDeviceClick) { - viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text20Style); - viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text16Style); + viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text18Style); + viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text14Style); } else { - viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text16Style); - viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text20Style); + viewBinding.messageTabNascentTitleTv.setTextAppearance(R.style.Text18Style); + viewBinding.messageTabRecoverTitleTv.setTextAppearance(R.style.Text14Style); } - +// viewBinding..topMoreBtn.setVisibility(View.VISIBLE); +// viewBinding.toolbarTopMessageCenterListRl.topMoreIv.setImageResource(R.drawable.clearall); mMessageAdapter = new MessageAdapter(_mActivity); viewBinding.messageRcv.setLayoutManager(new LinearLayoutManager(_mActivity)); viewBinding.messageRcv.setAdapter(mMessageAdapter); + pullToRefresh(); } + + /** + * 涓嬫媺鍒锋柊鐨勯�昏緫 + */ + protected void pullToRefresh() { + viewBinding.messageSrl.setDelegate(new BGARefreshLayout.BGARefreshLayoutDelegate() { + @Override + public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout) { + new AsyncTask<Void, Void, Void>() { + + @Override + protected Void doInBackground(Void... params) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + // 鎵ц浠诲姟锛堝鏇存柊UI銆佽烦杞瓑锛� + viewBinding.messageSrl.endRefreshing(); + loadNextPageMessageList(false, 1, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, true); + + } + }.execute(); + + + } + + + @Override + public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout) { + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... params) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + viewBinding.messageSrl.endLoadingMore(); + //鍔犺浇鏈�鏂版暟鎹畬鎴� + if (!isLoadingMore) { + // 婊戝姩鍒颁簡搴曢儴锛屾墽琛岀浉搴旂殑鎿嶄綔 + loadNextPageMessageList(false, ++mCurrentPage, mDeviceTypeFilterKye, mDeviceTypeFilterValue, mTypeFilterKye, mTypeFilterValue, mTimeTypeFilterKye, mTimeTypeFilterValue, false); + } + } + }.execute(); + return true; + } + }); + HDLRefreshViewHolder hdlRefreshViewHolder = new HDLRefreshViewHolder(_mActivity, true); + hdlRefreshViewHolder.setPullDownImageResource(R.mipmap.loading_44); + hdlRefreshViewHolder.setChangeToReleaseRefreshAnimResId(R.drawable.loading_refresh); + hdlRefreshViewHolder.setRefreshingAnimResId(R.drawable.loading_refresh_end); + viewBinding.messageSrl.setRefreshViewHolder(hdlRefreshViewHolder); + } + private void initData() { //杩涙潵璇诲彇涓�娆℃暟鎹�(涓轰簡鏇存柊currentPage锛宑urrentTotal杩欎釜鍊�),app鍚姩鏃跺�欒鍙栵紝涓轰簡鍒锋柊娑堟伅妯″潡鐨勮鏍� @@ -290,7 +371,7 @@ // 鍙栨秷绮樻�т簨浠� EventBus.getDefault().removeStickyEvent(eventBus); //杩涙潵璇诲彇涓�娆℃暟鎹�(涓轰簡鏇存柊currentPage锛宑urrentTotal杩欎釜鍊�) - initData(); +// initData(); HdlLogLogic.print("姝e湪鐐瑰嚮銆愭秷鎭��"); } @@ -351,6 +432,7 @@ if (messageListClass != null) { mCurrentTotal = (int) messageListClass.getTotalPage(); mCurrentPage = (int) messageListClass.getPageNo(); + mTotalCount = (int) messageListClass.getTotalCount(); updateListData(); } isLoadingMore = false; @@ -368,6 +450,7 @@ if (isShowLoading) { hideLoading(); } + HdlThreadLogic.toast(_mActivity, e.getMsg() + "(" + e.getCode() + ")"); } }); @@ -387,20 +470,25 @@ updateRecyclerViewList(); //鏄剧ず鏈淇℃伅鎬绘暟閲� getUnreadCount(); + if (isAlarmDeviceClick) { + refreshNascentTotalCount(mTotalCount); + } else { + refreshRecoverTotalCount(mTotalCount); + } //鏄剧ず娌℃暟鎹甎i鏍峰紡 nullDataUpdateUi(); + } }); } /** - * 鍒锋柊淇℃伅鏁伴噺鎬绘暟 + * 鍒锋柊鍙戦�佷腑娑堟伅鎬绘暟閲� * * @param nascentTotalCount 鍙戦�佷腑娑堟伅鎬绘暟閲� - * @param recoverTotalCount 鎶ヨ璁板綍娑堟伅鎬绘暟閲� */ - private void refreshAascentAndRecoverTotalCount(int nascentTotalCount, int recoverTotalCount) { + private void refreshNascentTotalCount(int nascentTotalCount) { HdlThreadLogic.runMainThread(new Runnable() { @Override public void run() { @@ -413,6 +501,20 @@ nascentTv.setText(s); } } + } + }); + + } + + /** + * 鍒锋柊鎶ヨ璁板綍娑堟伅鎬绘暟閲� + * + * @param recoverTotalCount 鎶ヨ璁板綍娑堟伅鎬绘暟閲� + */ + private void refreshRecoverTotalCount(int recoverTotalCount) { + HdlThreadLogic.runMainThread(new Runnable() { + @Override + public void run() { //鎶ヨ璁板綍鎬绘暟閲� TextView recoverTV = _mActivity.findViewById(R.id.message_tab_recover_title_tv); if (recoverTV != null) { @@ -500,8 +602,12 @@ if (unCountBean == null) { return; } - refreshAascentAndRecoverTotalCount(unCountBean.getUntreatedCount(), unCountBean.getProcessedCount()); refreshUnreadCount(unCountBean.getUnreadCount()); +// if (isRefreshTotalCount) { +// isRefreshTotalCount = false; + refreshNascentTotalCount(unCountBean.getUntreatedCount()); + refreshRecoverTotalCount(unCountBean.getProcessedCount()); +// } } }); @@ -509,10 +615,15 @@ @Override public void onFailure(HDLException e) { - TextView textView = _mActivity.findViewById(R.id.my_message_bottom_il2).findViewById(R.id.red_count_tv); - if (textView != null) { - textView.setVisibility(View.GONE); - } + HdlThreadLogic.runMainThread(new Runnable() { + @Override + public void run() { + TextView textView = _mActivity.findViewById(R.id.my_message_bottom_il2).findViewById(R.id.red_count_tv); + if (textView != null) { + textView.setVisibility(View.GONE); + } + } + }); } }); } @@ -537,6 +648,7 @@ map.put(getString(R.string.alarm_all_device_inverter), "INV"); map.put(getString(R.string.alarm_all_device_bms), "BMS"); map.put(getString(R.string.alarm_all_device_battery_cell), "BATTERY"); + map.put(getString(R.string.alarm_all_device_load_centre), "LOAD_CENTRE"); map.put(getString(R.string.alarm_all_grade), "");//璁剧瓑绾у叏閮� map.put(getString(R.string.alarm_all_grade_malfunction), "FAULT"); map.put(getString(R.string.alarm_all_grade_warning), "WARN"); @@ -569,6 +681,7 @@ stringList.add(getString(R.string.alarm_all_device_inverter)); stringList.add(getString(R.string.alarm_all_device_bms)); stringList.add(getString(R.string.alarm_all_device_battery_cell)); + stringList.add(getString(R.string.alarm_all_device_load_centre)); } break; case FilterType.type: { -- Gitblit v1.8.0