From b562a582ac3a288193e6e4f57c5eff8a344305a4 Mon Sep 17 00:00:00 2001
From: wxr <wxr@hdlchina.com.cn>
Date: 星期五, 27 九月 2024 13:52:17 +0800
Subject: [PATCH] Update AndroidManifest.xml
---
HDL_ON/UI/UI2/FuntionControlView/Music/MusicMain.cs | 511 ++++++++++++++++++++++++++------------------------------
1 files changed, 235 insertions(+), 276 deletions(-)
diff --git a/HDL_ON/UI/UI2/FuntionControlView/Music/MusicMain.cs b/HDL_ON/UI/UI2/FuntionControlView/Music/MusicMain.cs
index 01c7106..e41d821 100644
--- a/HDL_ON/UI/UI2/FuntionControlView/Music/MusicMain.cs
+++ b/HDL_ON/UI/UI2/FuntionControlView/Music/MusicMain.cs
@@ -3,19 +3,32 @@
using Shared;
using Shared.IO;
using System.Net;
+using HDL_ON.Entity;
+using HDL_ON.UI.UI2.FuntionControlView.Music;
+
namespace HDL_ON.UI.Music
{
public class MusicMain : FrameLayout
{
+ private static MusicMain s_Current = null;
+ public static MusicMain Current
+ {
+ get
+ {
+ if (s_Current == null)
+ {
+ s_Current = new MusicMain();
+ }
+ return s_Current;
+ }
+ }
/// <summary>
/// MusicMain瀵硅薄鏋勯�犲嚱鏁�
/// </summary>
public MusicMain()
{
Tag = "MusicMain";
- //杩涙潵闊充箰鍒楄〃鐣岄潰鍏堢Щ闄や箣鍓嶇嚎绋�;
- A31MusicModel.RemoveListThread();
}
/// <summary>
/// 閲嶅啓RemoveFromParent鏂规硶
@@ -23,8 +36,9 @@
public override void RemoveFromParent()
{
base.RemoveFromParent();
- clearA31Threads();
- A31MusicModel.ReadMusicStates();//杩涙潵娌℃湁闊充箰琚敹钘忚繃锛岄��鍑烘湁闊充箰琚敹钘忚繃
+ ClearA31Threads();
+ //杩涙潵娌℃湁闊充箰琚敹钘忚繃锛岄��鍑烘湁闊充箰琚敹钘忚繃
+ //A31MusicModel.ReadMusicStates();
}
/// <summary>
/// 鍒涘缓绾跨▼鍒楄〃
@@ -33,8 +47,9 @@
/// <summary>
/// 绉婚櫎绾跨▼
/// </summary>
- static void clearA31Threads()
+ static void ClearA31Threads()
{
+
var threads = threadLists.FindAll((obj) => { return obj.Name == "A31"; });
foreach (var thread in threads)
{
@@ -56,19 +71,20 @@
/// <summary>
/// 鏄剧ず鍔犺浇鐣岄潰
/// </summary>
- public static Loading loading = new Loading();
+ public static Loading loading = new Loading();
/// <summary>
/// 瀹氫箟鍏ㄥ眬瀵硅薄
/// </summary>
VerticalRefreshLayout verticalRefresh;
+
public void Show()
{
-
+
#region 鐣岄潰甯冨眬
this.BackgroundColor = MusicColor.ViewColor;
var topView = new TopView();
this.AddChidren(topView.TopFLayoutView());
- topView.topNameBtn.TextID =StringId.a31Music;
+ topView.topNameBtn.TextID = StringId.a31Music;
topView.clickBackBtn.MouseUpEventHandler += (sender, e) =>
{
RemoveFromParent();
@@ -78,214 +94,135 @@
{
Y = topView.fLayout.Bottom,
Height = Application.GetRealHeight(H_W.H - H_W.T_Height),
+ Name = "verticalRefresh",
};
this.AddChidren(verticalRefresh);
#endregion
verticalRefresh.BeginHeaderRefreshingAction += () =>
{
- SeachMusic(false);
-
+
+ ////鍙戦�佽鍙栭煶涔愭挱鏀惧櫒鐘舵�佺嚎绋�
+ SeachMusic();
+ verticalRefresh.EndHeaderRefreshing();
};
this.AddChidren(loading);
+ SeachMusic();
- if (A31MusicModel.A31MusicModelList.Count == 0)
- {
- SeachMusic(true);
- }
- else
- {
- clearA31Threads();
- //verticalRefresh.RemoveAll();
- for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
- {
- var a31player = A31MusicModel.A31MusicModelList[i];
- ///杩欎釜鐘舵�佹槸涔嬪墠淇濆瓨鐨勶紝鍔犺浇瀹屾垚鍚庤鏍囪涓轰笉鍦ㄧ嚎锛屽悗闈㈠啀璇诲彇姝g‘鐨勭姸鎬�
- if (!a31player.IsCanShow)
- {
- continue;
- }
- if (A31MusicModel.A31MusicModelList.Count - 1 == i)
- {
- a31player.IsEnd = true;
- }
- else
- {
- a31player.IsEnd = false;
- }
- ///鍔犺浇鐣岄潰鏃堕粯璁や笉鍦ㄧ嚎
- ///杩欓噷鏍囪鏄负浜嗕笉璇诲彇涓嶅湪绾挎挱鏀惧櫒鐘舵��
- a31player.IsOnLine = false;
- MusicListView(a31player);
- }
- ///璇诲彇姝g‘鐨勪俊鎭紝鍖呮嫭IP鍜岀鍙e強鍚嶇О
- SendMethod.Seach((obj) =>
- {
- try
- {
- if (obj == null)
- {
- ///杩欓噷瑕佽鍙栦富浠庡叧绯�
- readServerOrClientMode();
- A31MusicModel.Save();
- return;
- }
- var a31MusicModel = A31MusicModel.A31MusicModelList.Find((music) => music.UniqueDeviceName == obj.UniqueDeviceName);
- if (a31MusicModel != null)
- {
- a31MusicModel.IPAddress = obj.IPAddress;
- a31MusicModel.Port = obj.Port;
- a31MusicModel.Name = obj.Name;
- a31MusicModel.IsCanShow = true;
- a31MusicModel.IsOnLine = true;
- }
- }
- catch (Exception e) { MainPage.Log(e.Message); }
- });
- }
}
/// <summary>
/// 鍒锋柊鎾斁鍣ㄥ垪琛�
/// </summary>
- /// <param name="Yes">鏄惁鏄剧ず鍒锋柊鍥炬爣</param>
- void SeachMusic(bool Yes = false)
+ void SeachMusic()
{
- for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
+
+ Application.RunOnMainThread(() =>
{
- var a31player = A31MusicModel.A31MusicModelList[i];
- a31player.IsCanShow = false;
- a31player.IsOnLine = false;
- }
- if (Yes)
- {
- //涓轰簡绗竴娆¤繘鏉og涓�涓�;
- loading.Start();
- }
- SendMethod.Seach((obj) =>
- {
- if (obj == null)
+ verticalRefresh.RemoveAll();
+ A31MusicModel.A31MusicModelList.Clear();
+ var musicDeviceList= FunctionList.List.GetMusicList();
+ for (int i = 0; i < musicDeviceList.Count; i++)
{
- readServerOrClientMode();
- A31MusicModel.Save();
- if (!Yes)
+ var function = musicDeviceList[i];
+ var music = A31MusicModel.A31MusicModelList.Find((obj) =>
+ (obj.functionMusic.deviceId == function.deviceId && function.spk == SPK.MusicStandard) || (
+ obj.functionMusic.deviceId == function.deviceId && function.spk == SPK.AvMusic)
+ );
+ if (music == null)
{
- ///绛夊緟璺戝畬鍦ㄥ叧闂�
- verticalRefresh.EndHeaderRefreshing();
+ A31MusicModel.A31MusicModelList.Add(new A31MusicModel { functionMusic = function });
}
+ else
+ {
+ music.functionMusic = function;
+ }
+ }
+
+ for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
+ {
+
+ var a31player = A31MusicModel.A31MusicModelList[i];
+ //if (a31player.functionMusic.isOnline() == false)
+ //{
+ // //涓嶅湪绾夸笉鏄剧ず
+ // continue;
+ //}
+
Application.RunOnMainThread(() =>
{
- if (Yes)
+ try
{
- //涓轰簡绗竴娆¤繘鏉og涓�涓�;
- loading.Hide();
- }
- verticalRefresh.RemoveAll();
- for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
- {
- var a31player = A31MusicModel.A31MusicModelList[i];
- //杩欎釜鐘舵�佹槸涔嬪墠淇濆瓨鐨勶紝鍔犺浇瀹屾垚鍚庤鏍囪涓轰笉鍦ㄧ嚎锛屽悗闈㈠啀璇诲彇姝g‘鐨勭姸鎬�
- if (!a31player.IsCanShow)
- {
- continue;
- }
- if (A31MusicModel.A31MusicModelList.Count - 1 == i)
- {
- a31player.IsEnd = true;
- }
- else
- {
- a31player.IsEnd = false;
- }
MusicListView(a31player);
}
- //A31MusicModel.ReadMusicStates();
+ catch (Exception ex)
+ {
+ MainPage.Log("Error", $"MusicListView 鏂规硶寮傚父锛歿ex.StackTrace}");
+ }
+ });
+ }
+ ///杩涙潵璇讳竴娆¢煶涔愭挱鏀惧櫒鐘舵��
+ for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
+ {
+
+ var a31player = A31MusicModel.A31MusicModelList[i];
+ if (a31player.functionMusic.isOnline() == false)
+ {
+ //涓嶅湪绾夸笉璇诲彇
+ continue;
+ }
+ //鍙戦�佽鍙栭煶涔愭挱鏀惧櫒鐘舵�佺嚎绋�
+ System.Threading.Tasks.Task.Run(() =>
+ {
+ try
+ {
+
+ SendMethod.Current.RefreshDeviceStatus(new List<string> { a31player.functionMusic.deviceId });
+ System.Threading.Thread.Sleep(500);
+ }
+ catch { }
});
- return;
}
- var a31MusicModel = A31MusicModel.A31MusicModelList.Find((music) => { return music.UniqueDeviceName == obj.UniqueDeviceName; });
- if (a31MusicModel == null)
- {
- //涓嶆槸鎴戜滑鏀寔鐨勫搧鐗屼笉鏀寔
- if (obj.Name != null)
- {
- obj.sid = "030101123456780909020123AABB" + obj.UniqueDeviceName;
- A31MusicModel.A31MusicModelList.Add(obj);
- }
- }
- else
- {
- a31MusicModel.IPAddress = obj.IPAddress;
- a31MusicModel.Port = obj.Port;
- a31MusicModel.Name = obj.Name;
- a31MusicModel.IsCanShow = true;
- a31MusicModel.IsOnLine = true;
- }
+
});
}
/// <summary>
/// 鏄剧ず闊充箰鍒楄〃鐨勬柟娉�
/// </summary>
- void MusicListView(A31MusicModel a31player)
+ void MusicListView(A31MusicModel player)
{
+ /// <summary>
+ /// 涓轰簡闊充箰鍒锋柊鐘舵�佸畾涔夊叏灞�瀵硅薄
+ /// </summary>
MusicView musicView = new MusicView();
- musicView.View(verticalRefresh);
- musicView.singerBtn.Text = a31player.A31PlayStatus.Artist;
- musicView.songNameBtn.Text = a31player.A31PlayStatus.Title;
- musicView.musicNameBtn.Text = new View.DialogView { }.NamePlayer(a31player);
- if (a31player.IsEnd)
- {
- musicView.muiscFl.Height = Application.GetRealHeight(12 + 139 + 12);
- }
-
+ musicView.ViewAddChidren(verticalRefresh);
+ musicView.muiscFl.Tag = player.functionMusic;//澶氫釜闊充箰鎾斁鍣ㄦ洿鏂扮姸鎬佽鐢ㄥ埌
+ musicView.singerBtn.Text = player.functionMusic.GetAttrState(KeyProperty.song_name);
+ musicView.songNameBtn.Text = player.functionMusic.GetAttrState(KeyProperty.song_name);
+ musicView.musicNameBtn.Text = player.functionMusic.name;
+ //musicView.collectIconBtn.Visible = false;//鍏堟殏鏃堕殣钘忔敹钘忓姛鑳�
+ ///鏀惰棌浜嬩欢
musicView.collectIconBtn.MouseUpEventHandler += (sender, e) =>
{
musicView.collectIconBtn.IsSelected = !musicView.collectIconBtn.IsSelected;
- if (a31player.ServerClientType == 1)
+ if (musicView.collectIconBtn.IsSelected)
{
- if (musicView.collectIconBtn.IsSelected)
- {
- a31player.MainPlayCollection = true;
- }
- else
- {
- a31player.MainPlayCollection = false;
- }
+ player.functionMusic.collect = true;
}
else
{
- if (musicView.collectIconBtn.IsSelected)
- {
- a31player.collect = true;
- }
- else
- {
- a31player.collect = false;
- }
+ player.functionMusic.collect = false;
}
- A31MusicModel.Save();
+ player.functionMusic.CollectFunction();
};
- EventHandler<MouseEventArgs> clickMergence = (sender, e) =>
- {
- if (a31player.ServerClientType == 0)
- {
- new View.DialogView { }.PlayMergence(a31player);
- }
- else if (a31player.ServerClientType == 1)
- {
- new View.DialogView { }.DetachPlayMergence(a31player);
- }
- };
- musicView.mergeBjBtn.MouseUpEventHandler += clickMergence;
- musicView.mergeBtn.MouseUpEventHandler += clickMergence;
- musicView.mergeIconBtn.MouseUpEventHandler += clickMergence;
-
+ ///杩涘叆闊充箰涓婚〉浜嬩欢
EventHandler<MouseEventArgs> clickPlayView = (sender, e) =>
{
- A31MusicModel.Current = a31player;//褰撳墠鎾斁鍣�
+
+ A31MusicModel.Current = player;
var a31PlayMusicPage = new A31PlayMusicPage();
MainPage.BasePageView.AddChidren(a31PlayMusicPage);
a31PlayMusicPage.Show();
@@ -302,7 +239,10 @@
musicView.prevBtn.MouseDownEventHandler += (sender, e) =>
{
musicView.prevBtn.IsSelected = true;
- SendMethod.Previous(a31player);
+ player.functionMusic.SetAttrState(KeyProperty.song_step, ValueProperty.up);
+ Dictionary<string, string> dic = new Dictionary<string, string>();
+ dic.Add(KeyProperty.song_step, ValueProperty.up);
+ SendMethod.Current.SendControlCommand(player.functionMusic, dic);
};
musicView.prevBtn.MouseUpEventHandler += (sender, e) =>
{
@@ -311,46 +251,54 @@
///鏆傚仠/鎾斁鐐瑰嚮浜嬩欢
musicView.playBtn.MouseDownEventHandler += (sender, e) =>
{
+ string status = ValueProperty.off;
if (musicView.playBtn.IsSelected)
{
musicView.playBtn.IsSelected = false;
- SendMethod.Pause(a31player);
- a31player.A31PlayStatus.status = "pause";
+ status = ValueProperty.off;
}
else
{
musicView.playBtn.IsSelected = true;
- SendMethod.Play(a31player);
- a31player.A31PlayStatus.status = "play";
+ status = ValueProperty.on;
}
+ player.functionMusic.SetAttrState(KeyProperty.on_off, status);
+ Dictionary<string, string> dic = new Dictionary<string, string>();
+ dic.Add(KeyProperty.on_off, status);
+ SendMethod.Current.SendControlCommand(player.functionMusic, dic);
};
///涓嬩竴鏇茬偣鍑讳簨浠�
musicView.nextBtn.MouseDownEventHandler += (sender, e) =>
{
musicView.nextBtn.IsSelected = true;
- SendMethod.Next(a31player);
+ player.functionMusic.SetAttrState(KeyProperty.song_step, ValueProperty.down);
+ Dictionary<string, string> dic = new Dictionary<string, string>();
+ dic.Add(KeyProperty.song_step, ValueProperty.down);
+ SendMethod.Current.SendControlCommand(player.functionMusic, dic);
};
musicView.nextBtn.MouseUpEventHandler += (sender, e) =>
{
musicView.nextBtn.IsSelected = false;
};
-
+ //鏇存柊鐘舵�佺嚎绋�
var musicThread = new System.Threading.Thread(() =>
{
while (true)
{
- System.Threading.Thread.Sleep(1000);
- if (!a31player.IsOnLine)
+ if (!player.functionMusic.isOnline())
{
+ ///涓嶅湪绾夸笉璇荤姸鎬�
continue;
}
- SendMethod.ReadStatus(a31player);
+ //SendMethod.ReadStatus(player);
+ SendMethod.Current.GetDeviceStatus(ref player, new List<string> { player.functionMusic.deviceId }, player.functionMusic.sid);
+ System.Threading.Thread.Sleep(1000);
Application.RunOnMainThread(() =>
{
- musicView.singerBtn.Text = a31player.A31PlayStatus.Artist;
- musicView.songNameBtn.Text = a31player.A31PlayStatus.Title;
- musicView.musicNameBtn.Text = new View.DialogView { }.NamePlayer(a31player);
- if (a31player.A31PlayStatus.status == "play")
+ musicView.singerBtn.Text = player.functionMusic.GetAttrState(KeyProperty.song_name);
+ musicView.songNameBtn.Text = player.functionMusic.GetAttrState(KeyProperty.song_name);
+ musicView.musicNameBtn.Text = player.functionMusic.name;
+ if (player.functionMusic.GetAttrState(KeyProperty.on_off) == ValueProperty.on)
{
musicView.playBtn.IsSelected = true;
}
@@ -358,28 +306,15 @@
{
musicView.playBtn.IsSelected = false;
}
- musicView.regionBtn.Text = a31player.GetRoomListName();
- if (a31player.ServerClientType == 1)
+ musicView.regionBtn.Text = player.functionMusic.GetRoomListName();
+
+ if (player.functionMusic.collect)
{
- if (a31player.MainPlayCollection)
- {
- musicView.collectIconBtn.IsSelected = true;
- }
- else
- {
- musicView.collectIconBtn.IsSelected = false;
- }
+ musicView.collectIconBtn.IsSelected = true;
}
else
{
- if (a31player.collect)
- {
- musicView.collectIconBtn.IsSelected = true;
- }
- else
- {
- musicView.collectIconBtn.IsSelected = false;
- }
+ musicView.collectIconBtn.IsSelected = false;
}
});
}
@@ -388,99 +323,123 @@
musicThread.Start();
threadLists.Add(musicThread);
}
+
/// <summary>
- /// 璇诲彇涓讳粠鍏崇郴
+ ///鎸囧畾鍒锋柊鐣岄潰
/// </summary>
- void readServerOrClientMode()
+ /// <param name="strView">鍒ゆ柇瀛楃</param>
+ public void RefreshView(AlinkStatusData alinkStatusData)
{
- try
+ if (alinkStatusData == null || alinkStatusData.status.Count == 0)
{
- for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
+ return;
+ }
+ Application.RunOnMainThread(() =>
+ {
+ try
{
- var a31player = A31MusicModel.A31MusicModelList[i];
- if (!a31player.IsOnLine)
+ for (int a =0; a < MainPage.BasePageView.ChildrenCount; a++)
{
- continue;
- }
- try
- {
- a31player.ServerClientType = 0;
- var result = SendMethod.OpenWeb("http://" + a31player.IPAddress + "/httpapi.asp?command=multiroom:getSlaveList");
- if (result == null && result == "Failed")
+ var view = MainPage.BasePageView.GetChildren(a);
+ if (view.GetType() == typeof(MusicMain))
{
- result = SendMethod.OpenWeb("http://" + a31player.IPAddress + "/httpapi.asp?command=multiroom:getSlaveList");
- }
- if (result != null && result != "Failed")
- {
- a31player.Slave = Newtonsoft.Json.JsonConvert.DeserializeObject<Slaves>(result);
- }
- }
- catch (Exception e)
- {
- var d = e.Message;
- }
- }
-
- //鍒嗘瀽涓讳粠鍏崇郴
- for (int i = 0; i < A31MusicModel.A31MusicModelList.Count; i++)
- {
- var a31player = A31MusicModel.A31MusicModelList[i];
- if (!a31player.IsOnLine)
- {
- continue;
- }
- try
- {
- if (a31player.Slave != null && "0" != a31player.Slave.slaves)
- {
- a31player.ServerClientType = 1;//涓荤殑
- string str = a31player.Name;
- for (int j = 0; j < a31player.Slave.slave_list.Count; j++)
+ var musicMain = view as MusicMain;
+ if (musicMain != null)
{
-
- var slave = a31player.Slave.slave_list[j];
- str = str + "+" + slave.name;
- var tempA31Player = A31MusicModel.A31MusicModelList.Find((obj) => slave.uuid.Replace("uuid:", "") == obj.UniqueDeviceName);
- if (tempA31Player == null)
+ for (int b = 0; b < musicMain.ChildrenCount; b++)
{
- A31MusicModel.A31MusicModelList.Add(new A31MusicModel
+ var view1 = musicMain.GetChildren(b);
+ if (view1.GetType() == typeof(VerticalRefreshLayout))
{
- sid = "030101123456780909020123AABB" + slave.uuid.Replace("uuid:", ""),
- ServerClientType = -1,//浠庣殑
- IPAddress = slave.ip,
- MainPlayIP = a31player.IPAddress,
- UniqueDeviceName = slave.uuid.Replace("uuid:", ""),
- Name = slave.name,
- IsCanShow = false,
- IsOnLine = false,//true浣滅敤涓轰簡璇诲彇浠庢挱鏀惧櫒鐨勯煶閲�
- });
- }
- //濡傛灉鎵惧埌灏辨洿鏂颁负浠庣殑
- else
- {
- tempA31Player.ServerClientType = -1;//浠庣殑
- tempA31Player.IPAddress = slave.ip;
- tempA31Player.MainPlayIP = a31player.IPAddress;
- tempA31Player.Name = slave.name;
- tempA31Player.UniqueDeviceName = slave.uuid.Replace("uuid:", "");
- tempA31Player.IsCanShow = false;
- tempA31Player.IsOnLine = false;//true浣滅敤涓轰簡璇诲彇浠庢挱鏀惧櫒鐨勯煶閲�
+ var vv = view1 as VerticalRefreshLayout;
+ if (vv != null && vv.Name == "verticalRefresh")
+ {
+ for (int c = 0; c < vv.ChildrenCount; c++)
+ {
+ var viewfl = vv.GetChildren(c);
+ if (viewfl.GetType() == typeof(FrameLayout))
+ {
+ var fl = viewfl as FrameLayout;
+ if ((fl.Tag as Function).sid!= alinkStatusData.sid) {
+ //涓嶆槸褰撳墠闊充箰涓嶄細鏇存柊鐘舵��
+ continue;
+ }
+ if (fl != null && fl.Name == "parentfl")
+ {
+ for (int i = 0; i < fl.ChildrenCount; i++)
+ {
+ var viewfl1 = fl.GetChildren(i);
+ if (viewfl1.GetType() == typeof(FrameLayout))
+ {
+ var fl1 = viewfl1 as FrameLayout;
+ if (fl1 != null && fl1.Name == "musicparentfl")
+ {
+ for (int j = 0; j < fl1.ChildrenCount; j++)
+ {
+
+ if (fl1.GetChildren(j).GetType() == typeof(Button))
+ {
+ var btn = fl1.GetChildren(j) as Button;
+ if (btn == null ||btn.Name==null)
+ {
+ continue;
+ }
+ switch (btn.Name)
+ {
+ case "song":
+ {
+ var s = alinkStatusData.status.Find((o) => o.key == KeyProperty.song_name);
+ if (s != null)
+ {
+ btn.Text = s.value;
+ }
+ }
+ break;
+ case "playstatus":
+ {
+
+ var s = alinkStatusData.status.Find((o) => o.key == KeyProperty.on_off);
+ if (s != null)
+ {
+ if (s.value == ValueProperty.on)
+ {
+ btn.IsSelected = true;
+ }
+ else
+ {
+ btn.IsSelected = false;
+ }
+ }
+ }
+ break;
+ }
+
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ }
+ }
+
+ }
}
}
- a31player.MainPlayName = str;
+
}
}
- catch (Exception e)
- {
- var ss = e.Message;
- }
- }
- }
- catch { }
+ }
+ catch { }
+ });
}
+
}
}
--
Gitblit v1.8.0