Avalonia 實現聊天訊息渲染、圖文混排(支援Windows、Linux、信創國產OS)

2023-08-22 06:01:50

    在實現即時通訊軟體或聊天軟體時,渲染文字表情、圖文混排是一項非常繁瑣的工作,再加上還要支援GIF動圖、參照訊息、撤回訊息、名片等不同樣式的訊息渲染時,就更加麻煩了。

       好在我們可以使用 ESFramework 提供的 IChatRender 元件,使用它我們就能輕鬆實現類似於微信聊天訊息的渲染效果。IChatRender 支援 Windows、Linux(包括國產OS)。在Windows平臺上提供了基於 WinForm 和基於 WPF 的實現,在Linux上則是基於Avalonia 實現的。

  廢話不多說,先上張渲染Demo的效果圖(該Demo原始碼可於文末下載):   

       

一.  支援的聊天訊息型別

      IChatRender 支援渲染的聊天訊息型別包括: 

(1)文字表情混排。

(2)圖片,GIF 動圖。

(3)檔案傳輸進度及控制。

(4)個人名片、群名片。

(5)參照訊息。

(6)語音訊息。

(7)語音通話。

(8)視訊通話。 

(9)撤回訊息、刪除訊息。       

二. IChatRender 介面定義

    IChatRender 介面的定義具體如下所示:

      /// <summary>
        /// 渲染名片 
        /// </summary>
        /// <param name="msgID">聊天記錄ID</param>
        /// <param name="userID">傳送者</param>
        /// <param name="cardUserID">名片上的個人ID</param>
        /// <param name="index">插入聊天記錄的位置,預設是放到最後面</param>
        void AddChatItemCard(string msgID ,string userID, string cardUserID ,int? index = null);

        /// <summary>
        /// 渲染檔案 
        /// </summary> 
        /// <param name="fileName">檔名稱</param>
        /// <param name="fileSize">檔案大小</param>
        /// <param name="state">檔案狀態</param> 
        void AddChatItemFile(string msgID, string userID, string fileName, ulong fileSize, FileTransState state, int? index = null);

        /// <summary>
        /// 渲染圖片
        /// </summary> 
        /// <param name="image">影象</param>
        /// <param name="imgSize">影象大小</param>
        /// <param name="observerable">預設傳null</param> 
        void AddChatItemImage(string msgID, string userID, object image, Size imgSize ,IProgressObserverable observerable = null, int? index = null);

        /// <summary>
        /// 渲染文字表情
        /// </summary> 
        /// <param name="text">內容,在渲染文字的內容中用 [000]來代表第一個表情,[001]即是二個表情,以此類推</param>
        /// <param name="referenced">參照內容可以是文字、圖片、檔案或名片</param>
        /// <param name="textColor">文字顏色</param> 
        void AddChatItemText(string msgID, string userID, string text, ReferencedChatMessage referenced = null, Color? textColor = null, int? index = null);

        /// <summary>
        /// 渲染悄悄話,預設顯示內容—>> 悄悄話
        /// </summary> 
        void AddChatItemSnap(string msgID, string userID, int? index = null);

        /// <summary>
        /// 渲染語音訊息
        /// </summary> 
        /// <param name="audioMessageSecs">語音時長</param>
        /// <param name="audioMessage">語音簡訊</param> 
        void AddChatItemAudio(string msgID, string userID, int audioMessageSecs, object audioMessage, int? index = null);

        /// <summary>
        /// 渲染多媒體通話型別
        /// </summary> 
        /// <param name="duration">通話時長</param>
        /// <param name="isAudioCommunicate">通話型別(語音/視訊)</param> 
        void AddChatItemMedia(string msgID, string userID, string duration, bool isAudioCommunicate, int? index = null); 

        /// <summary>
        /// 渲染系統訊息
        /// </summary>
        /// <param name="msg">系統訊息內容</param> 
        void AddChatItemSystemMessage(string msg, int? index = null);

        /// <summary>
        /// 渲染訊息的傳送時間
        /// </summary>
        /// <param name="dt">傳送時間</param> 
        void AddChatItemTime(DateTime dt, int? index = null);   

        /// <summary>
        /// 自己撤回訊息 
        /// </summary> 
        void RecallChatMessage(string msgID);

        /// <summary>
        /// 其他使用者撤回訊息 
        /// </summary> 
        /// <param name="operatorName">操作者</param>
        void RecallChatMessage(string msgID ,string operatorName);

        /// <summary>
        /// 刪除對應的記錄
        /// </summary> 
        void RemoveChatMessage(string msgID);

三.  建立 IChatRender 範例

       可以通過呼叫ESFramework.Extensions.ChatRendering.ChatRenderFactory 的靜態方法 CreateChatRender 建立一個 IChatRender 範例。

        /// <param name="provider">提供必要的資訊給聊天渲染器</param>
        /// <param name="ctrl">要在其表面渲染的UI控制元件</param>
        /// <param name="myID">自己的ID</param>
        /// <param name="destID">對方ID、或群ID</param>
        /// <param name="isGroup">群聊/單聊</param>
        /// <returns></returns>
        public static IChatRender CreateChatRender(ISysRender sysRender,IRenderDataProvider provider, IChatControl ctrl, string myID, string destID, bool isGroup);       

      第一個引數 sysRender 用於完成特定平臺上的基礎渲染繪製實現,比如 Winform 版的實現,WPF版的實現,以及Avalonia版的實現。

      ISysRender 介面的定義如下所示:

      

      在文末可下載的原始碼中,AvaloniaRender 類就實現了 ISysRender 介面。由於程式碼量較大,這裡就不貼出來了,大家可自行參看。

      第二個引數 IRenderDataProvider 用於在 IChatRender  渲染時,能從該介面獲取必要的資訊(如使用者的頭像、名稱、表情圖片等)。 

      第三個引數 則是要在其表面進行渲染的UI控制元件。 

四. 擴充套件自定義訊息渲染

      如果需要渲染自定義的訊息,可以呼叫 IChatRender 的 AddChatItemCustomized 方法插入要渲染的自定義訊息。

        /// <summary>
        /// 插入要渲染的自定義訊息。
        /// </summary>       
        void AddChatItemCustomized(IChatItem item, int? index = null);

       自定義的訊息可以從 BaseChatItem 繼承,然後override複寫其幾個方法就可以了。具體可以參見文末demo原始碼中的自定義訊息渲染的實現。

五. Demo 原始碼下載

      ChatRenderDemo 原始碼連結 1: Linux 端(Avalonia) 原始碼

      ChatRenderDemo 原始碼連結  2: Windows 端 + Linux 端 原始碼

      原始碼解決方案中包括三個專案:

(1)ChatRenderDemo.WPF:   該Demo的Windows端(基於WPF)。

(2)ChatRenderDemo.WinForm: 該Demo的Windows端(基於WinForm)。 

(3)ChatRenderDemo.Linux:     該Demo的Linux使用者端(基於.NetCore),支援在統信UOS、銀河麒麟等國產OS上執行。  

 注:Linux 端內建的是x86/x64非託管so庫,若需要其它架構的so,可以評論區留下email,到時我會發給大家。