소스 검색

im聊天界面功能

fancy 5 년 전
부모
커밋
e1fa7d80c3

+ 8 - 0
o2ios/O2Platform.xcodeproj/project.pbxproj

@@ -123,6 +123,8 @@
 		B1489B1D248E0F4D009EE9FD /* IMChatViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B1B248E0F4D009EE9FD /* IMChatViewController.xib */; };
 		B1489B1D248E0F4D009EE9FD /* IMChatViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B1B248E0F4D009EE9FD /* IMChatViewController.xib */; };
 		B1489B51248E192D009EE9FD /* IMChatMessageViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */; };
 		B1489B51248E192D009EE9FD /* IMChatMessageViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */; };
 		B1489B52248E192D009EE9FD /* IMChatMessageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */; };
 		B1489B52248E192D009EE9FD /* IMChatMessageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */; };
+		B1489BFE2490BE51009EE9FD /* IMChatMessageSendViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */; };
+		B1489BFF2490BE51009EE9FD /* IMChatMessageSendViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */; };
 		B14B339F2356EB1500442968 /* CloudFileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B339E2356EB1500442968 /* CloudFileViewModel.swift */; };
 		B14B339F2356EB1500442968 /* CloudFileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B339E2356EB1500442968 /* CloudFileViewModel.swift */; };
 		B14E07532301137F00AE85A0 /* ContactPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */; };
 		B14E07532301137F00AE85A0 /* ContactPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */; };
 		B14E07862301418400AE85A0 /* ContactUnitPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */; };
 		B14E07862301418400AE85A0 /* ContactUnitPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */; };
@@ -1441,6 +1443,8 @@
 		B1489B1B248E0F4D009EE9FD /* IMChatViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatViewController.xib; sourceTree = "<group>"; };
 		B1489B1B248E0F4D009EE9FD /* IMChatViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatViewController.xib; sourceTree = "<group>"; };
 		B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatMessageViewCell.swift; sourceTree = "<group>"; };
 		B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatMessageViewCell.swift; sourceTree = "<group>"; };
 		B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageViewCell.xib; sourceTree = "<group>"; };
 		B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageViewCell.xib; sourceTree = "<group>"; };
+		B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatMessageSendViewCell.swift; sourceTree = "<group>"; };
+		B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageSendViewCell.xib; sourceTree = "<group>"; };
 		B14B339E2356EB1500442968 /* CloudFileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileViewModel.swift; sourceTree = "<group>"; };
 		B14B339E2356EB1500442968 /* CloudFileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileViewModel.swift; sourceTree = "<group>"; };
 		B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactUnitPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactUnitPickerViewController.swift; sourceTree = "<group>"; };
@@ -2595,6 +2599,8 @@
 				B1173A662488CD5B005075F0 /* IMConversationItemCell.xib */,
 				B1173A662488CD5B005075F0 /* IMConversationItemCell.xib */,
 				B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */,
 				B1489B4F248E192D009EE9FD /* IMChatMessageViewCell.swift */,
 				B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */,
 				B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */,
+				B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */,
+				B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */,
 			);
 			);
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -5609,6 +5615,7 @@
 				E4B889071D9D4C7E002E1A46 /* podfile in Resources */,
 				E4B889071D9D4C7E002E1A46 /* podfile in Resources */,
 				E46E6C841DD41F5D00AB7561 /* ZSSimage@2x.png in Resources */,
 				E46E6C841DD41F5D00AB7561 /* ZSSimage@2x.png in Resources */,
 				E4B697012075DE5F0062F6E8 /* OOGuidePageController.xib in Resources */,
 				E4B697012075DE5F0062F6E8 /* OOGuidePageController.xib in Resources */,
+				B1489BFF2490BE51009EE9FD /* IMChatMessageSendViewCell.xib in Resources */,
 				E4D23110209C40F600837868 /* OOPersonCollectionViewCell.xib in Resources */,
 				E4D23110209C40F600837868 /* OOPersonCollectionViewCell.xib in Resources */,
 				B167F7672362C60200F182B8 /* CloudFileMoveFolderCell.xib in Resources */,
 				B167F7672362C60200F182B8 /* CloudFileMoveFolderCell.xib in Resources */,
 				E46E6CAD1DD41F5D00AB7561 /* ZSSundo.png in Resources */,
 				E46E6CAD1DD41F5D00AB7561 /* ZSSundo.png in Resources */,
@@ -6495,6 +6502,7 @@
 				E4C24BD920844F3C00E426B0 /* JCFeedbackViewController.swift in Sources */,
 				E4C24BD920844F3C00E426B0 /* JCFeedbackViewController.swift in Sources */,
 				E4C24C4C208D7EDE00E426B0 /* OOCDLCell.swift in Sources */,
 				E4C24C4C208D7EDE00E426B0 /* OOCDLCell.swift in Sources */,
 				B158E95E215DD3F500AB2727 /* AIConstants.swift in Sources */,
 				B158E95E215DD3F500AB2727 /* AIConstants.swift in Sources */,
+				B1489BFE2490BE51009EE9FD /* IMChatMessageSendViewCell.swift in Sources */,
 				E4BF45D71E74FB0C008B52F0 /* ImageSlidesShowView.swift in Sources */,
 				E4BF45D71E74FB0C008B52F0 /* ImageSlidesShowView.swift in Sources */,
 				E4C24B5820844F3C00E426B0 /* SAIInputItem.swift in Sources */,
 				E4C24B5820844F3C00E426B0 /* SAIInputItem.swift in Sources */,
 				E40E24DF20B7E66E009F8BE7 /* O2BBSCreatorView.swift in Sources */,
 				E40E24DF20B7E66E009F8BE7 /* O2BBSCreatorView.swift in Sources */,

+ 44 - 8
o2ios/O2Platform/App/IM-聊天/IMChatViewController.swift

@@ -8,6 +8,7 @@
 
 
 import UIKit
 import UIKit
 import CocoaLumberjack
 import CocoaLumberjack
+import O2OA_Auth_SDK
 
 
 class IMChatViewController: UIViewController {
 class IMChatViewController: UIViewController {
 
 
@@ -39,7 +40,10 @@ class IMChatViewController: UIViewController {
         self.tableView.delegate = self
         self.tableView.delegate = self
         self.tableView.dataSource = self
         self.tableView.dataSource = self
         self.tableView.register(UINib(nibName: "IMChatMessageViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageViewCell")
         self.tableView.register(UINib(nibName: "IMChatMessageViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageViewCell")
+        self.tableView.register(UINib(nibName: "IMChatMessageSendViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageSendViewCell")
         self.tableView.separatorStyle = .none
         self.tableView.separatorStyle = .none
+        self.tableView.rowHeight = UITableView.automaticDimension
+        self.tableView.estimatedRowHeight = 144
         self.messageInputView.delegate = self
         self.messageInputView.delegate = self
 
 
         //底部安全距离 老机型没有
         //底部安全距离 老机型没有
@@ -48,7 +52,19 @@ class IMChatViewController: UIViewController {
         self.bottomBar.topBorder(width: 1, borderColor: base_gray_color.alpha(0.5))
         self.bottomBar.topBorder(width: 1, borderColor: base_gray_color.alpha(0.5))
         self.messageInputView.backgroundColor = base_gray_color
         self.messageInputView.backgroundColor = base_gray_color
 
 
-
+        //标题
+        if let c = self.conversation {
+            var person = ""
+            c.personList?.forEach({ (p) in
+                if  p != O2AuthSDK.shared.myInfo()?.distinguishedName {
+                    person = p
+                }
+            })
+            if !person.isEmpty {
+                self.title = person.split("@").first ?? ""
+            }
+        }
+        //获取聊天数据
         self.loadMsgList(page: page)
         self.loadMsgList(page: page)
     }
     }
 
 
@@ -59,6 +75,9 @@ class IMChatViewController: UIViewController {
                 self.chatMessageList = list
                 self.chatMessageList = list
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
                     self.tableView.reloadData()
                     self.tableView.reloadData()
+                    if self.chatMessageList.count > 0 {
+                        self.tableView.scrollToRow(at: IndexPath(row: self.chatMessageList.count-1, section: 0), at: .bottom, animated: true)
+                    }
                 }
                 }
             }
             }
         } else {
         } else {
@@ -92,15 +111,32 @@ extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
     }
     }
 
 
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        return tableView.dequeueReusableCell(withIdentifier: "IMChatMessageViewCell", for: indexPath)
-    }
-    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
-        guard let c = cell as? IMChatMessageViewCell else {
-            return
+        let msg = self.chatMessageList[indexPath.row]
+        if msg.createPerson == O2AuthSDK.shared.myInfo()?.distinguishedName { //发送者
+            if let cell = tableView.dequeueReusableCell(withIdentifier: "IMChatMessageSendViewCell", for: indexPath) as? IMChatMessageSendViewCell {
+                cell.setContent(item: self.chatMessageList[indexPath.row])
+                return cell
+            }
+        }else {
+            if let cell = tableView.dequeueReusableCell(withIdentifier: "IMChatMessageViewCell", for: indexPath) as? IMChatMessageViewCell {
+                cell.setContent(item: self.chatMessageList[indexPath.row])
+                return cell
+            }
         }
         }
-        //todo
-        c.setContent(item: self.chatMessageList[indexPath.row])
+        return UITableViewCell()
+    }
+    
+    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        
+        tableView.deselectRow(at: indexPath, animated: false)
     }
     }
+//    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
+//        guard let c = cell as? IMChatMessageViewCell else {
+//            return
+//        }
+//        //todo
+//        c.setContent(item: self.chatMessageList[indexPath.row])
+//    }
 
 
 
 
 }
 }

+ 8 - 1
o2ios/O2Platform/App/IM-聊天/IMViewModel.swift

@@ -43,7 +43,14 @@ extension IMViewModel {
                 let response = OOResult<BaseModelClass<[IMMessageInfo]>>(result)
                 let response = OOResult<BaseModelClass<[IMMessageInfo]>>(result)
                 if response.isResultSuccess() {
                 if response.isResultSuccess() {
                     if let list = response.model?.data {
                     if let list = response.model?.data {
-                        fulfill(list)
+                        //列表翻转
+                        let rList = list.sorted { (f, s) -> Bool in
+                            if let ft = f.createTime, let st = s.createTime {
+                                return ft.toDate(formatter: "yyyy-MM-dd HH:mm:ss") < st.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
+                            }
+                            return true
+                        }
+                        fulfill(rList)
                     }else {
                     }else {
                         reject(OOAppError.apiEmptyResultError)
                         reject(OOAppError.apiEmptyResultError)
                     }
                     }

+ 133 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageSendViewCell.swift

@@ -0,0 +1,133 @@
+//
+//  IMChatMessageSendViewCell.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/10.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+
+class IMChatMessageSendViewCell: UITableViewCell {
+    @IBOutlet weak var timeLabel: UILabel!
+    @IBOutlet weak var avatarImageView: UIImageView!
+    @IBOutlet weak var nameLabel: UILabel!
+     
+    @IBOutlet weak var messageBackgroundView: UIView!
+    
+    @IBOutlet weak var messageBgWidth: NSLayoutConstraint!
+    @IBOutlet weak var messageBgHeight: NSLayoutConstraint!
+    
+    
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+    }
+
+    override func setSelected(_ selected: Bool, animated: Bool) {
+        super.setSelected(selected, animated: animated)
+    }
+    
+    func setContent(item: IMMessageInfo) {
+        //time
+        if let time = item.createTime {
+            let date = time.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
+            self.timeLabel.text = date.friendlyTime()
+        }
+        //name avatart
+        if let person = item.createPerson {
+            let urlstr = AppDelegate.o2Collect.generateURLWithAppContextKey(ContactContext.contactsContextKeyV2, query: ContactContext.personIconByNameQueryV2, parameter: ["##name##":person as AnyObject], generateTime: false)
+            if let u = URL(string: urlstr!) {
+                self.avatarImageView.hnk_setImageFromURL(u)
+            }else {
+                self.avatarImageView.image = UIImage(named: "icon_men")
+            }
+            //姓名
+            self.nameLabel.text = person.split("@").first ?? ""
+        }else {
+            self.avatarImageView.image = UIImage(named: "icon_men")
+            self.nameLabel.text = ""
+        }
+        self.messageBackgroundView.removeSubviews()
+        if let jsonBody = item.body, let body = parseJson(msg: jsonBody) {
+            if body.type == o2_im_msg_type_emoji {
+                emojiMsgRender(emoji: body.body!)
+            }else {
+                textMsgRender(msg: body.body!)
+            }
+        }
+    }
+    
+    
+    private func emojiMsgRender(emoji: String) {
+        let emojiSize = 36
+        let width = CGFloat(emojiSize + 20)
+        let height = CGFloat(emojiSize + 20)
+        self.messageBgWidth.constant = width
+        self.messageBgHeight.constant = height
+        //背景图片
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
+        let insets = UIEdgeInsets(top: 28, left: 5, bottom: 5, right: 10); // 上、左、下、右
+        var bubble = UIImage(named: "chat_bubble_outgoing")
+        bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
+        bgImg.image = bubble
+        self.messageBackgroundView.addSubview(bgImg)
+        //表情图
+        let emojiImage = UIImageView(frame: CGRect(x: 0, y: 0, width: emojiSize, height: emojiSize))
+        let bundle = Bundle().o2EmojiBundle(anyClass: IMChatMessageSendViewCell.self)
+        let path = o2ImEmojiPath(emojiBody: emoji)
+        emojiImage.image = UIImage(named: path, in: bundle, compatibleWith: nil)
+        emojiImage.translatesAutoresizingMaskIntoConstraints = false
+        self.messageBackgroundView.addSubview(emojiImage)
+        let top = NSLayoutConstraint(item: emojiImage, attribute: .top, relatedBy: .equal, toItem: emojiImage.superview!, attribute: .top, multiplier: 1, constant: 10)
+        let bottom = NSLayoutConstraint(item: emojiImage.superview! , attribute: .bottom, relatedBy: .equal, toItem: emojiImage, attribute: .bottom, multiplier: 1, constant: 10)
+        let left = NSLayoutConstraint(item: emojiImage, attribute: .leading, relatedBy: .equal, toItem: emojiImage.superview!, attribute: .leading, multiplier: 1, constant: 10)
+        let right = NSLayoutConstraint(item: emojiImage.superview!, attribute: .trailing, relatedBy: .equal, toItem: emojiImage, attribute: .trailing, multiplier: 1, constant: 10)
+        NSLayoutConstraint.activate([top, bottom, left, right])
+    }
+    
+    private func textMsgRender(msg: String) {
+        let size = calTextSize(str: msg)
+        self.messageBgWidth.constant = size.width + 20
+        self.messageBgHeight.constant = size.height + 20
+        //背景图片
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 20, height: size.height + 20))
+        let insets = UIEdgeInsets(top: 28, left: 5, bottom: 5, right: 10); // 上、左、下、右
+        var bubble = UIImage(named: "chat_bubble_outgoing")
+        bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
+        bgImg.image = bubble
+        self.messageBackgroundView.addSubview(bgImg)
+        //文字
+        let label = generateMessagelabel(str: msg, size: size)
+        label.translatesAutoresizingMaskIntoConstraints = false
+        self.messageBackgroundView.addSubview(label)
+        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
+//        let bottom = NSLayoutConstraint(item: label.superview! , attribute: .bottom, relatedBy: .equal, toItem: label, attribute: .bottom, multiplier: 1, constant: 10)
+        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
+        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
+        NSLayoutConstraint.activate([top, left, right])
+    }
+    
+    private func generateMessagelabel(str: String, size: CGSize) -> UILabel {
+        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
+        label.text = str
+        label.font = UIFont.systemFont(ofSize: 16)
+        label.numberOfLines = 0
+        label.lineBreakMode = .byCharWrapping
+        label.preferredMaxLayoutWidth = size.width
+        
+        return label
+    }
+    
+    
+    private func calTextSize(str: String) -> CGSize {
+        let size = CGSize(width: 176, height: CGFloat(MAXFLOAT))
+        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
+    }
+    
+    //解析json为消息对象
+    private func parseJson(msg: String) -> IMMessageBodyInfo? {
+        return IMMessageBodyInfo.deserialize(from: msg)
+    }
+    
+}

+ 84 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageSendViewCell.xib

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="129" id="KGk-i7-Jjw" customClass="IMChatMessageSendViewCell" customModule="O2Platform" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="129"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="129"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="06-09 13:02" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k0L-ig-bhB">
+                        <rect key="frame" x="14" y="5" width="292" height="18"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="18" id="MJ9-1n-RP4"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                        <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dRS-Ex-V2s">
+                        <rect key="frame" x="258" y="31" width="48" height="48"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="48" id="ALp-AJ-k89"/>
+                            <constraint firstAttribute="height" constant="48" id="U0b-CA-lXO"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="24"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </imageView>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="姓名" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O0d-aO-DEf">
+                        <rect key="frame" x="219" y="31" width="29" height="24"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="24" id="hV4-hf-Q8a"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                        <nil key="textColor"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="73U-Yu-hhb">
+                        <rect key="frame" x="72" y="63" width="176" height="42"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="42" id="9m9-a5-elu"/>
+                            <constraint firstAttribute="width" constant="176" id="B2b-ep-gRb"/>
+                        </constraints>
+                    </view>
+                </subviews>
+                <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
+                <constraints>
+                    <constraint firstItem="k0L-ig-bhB" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="5" id="59J-ml-PYh"/>
+                    <constraint firstItem="73U-Yu-hhb" firstAttribute="top" secondItem="O0d-aO-DEf" secondAttribute="bottom" constant="8" id="6MU-oN-E2m"/>
+                    <constraint firstItem="k0L-ig-bhB" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="6QF-aq-QM6"/>
+                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="top" secondItem="k0L-ig-bhB" secondAttribute="bottom" constant="8" id="JfT-ce-huE"/>
+                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="leading" secondItem="73U-Yu-hhb" secondAttribute="trailing" constant="10" id="Njy-Bc-KtC"/>
+                    <constraint firstItem="O0d-aO-DEf" firstAttribute="top" secondItem="k0L-ig-bhB" secondAttribute="bottom" constant="8" id="VFs-xs-kta"/>
+                    <constraint firstAttribute="trailing" secondItem="dRS-Ex-V2s" secondAttribute="trailing" constant="14" id="gmx-Y3-81p"/>
+                    <constraint firstAttribute="bottomMargin" secondItem="73U-Yu-hhb" secondAttribute="bottom" constant="10" id="j9W-5A-2om"/>
+                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="leading" secondItem="O0d-aO-DEf" secondAttribute="trailing" constant="10" id="ngR-6P-5QW"/>
+                    <constraint firstAttribute="trailing" secondItem="k0L-ig-bhB" secondAttribute="trailing" constant="14" id="y21-uR-MhX"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
+            <connections>
+                <outlet property="avatarImageView" destination="dRS-Ex-V2s" id="Els-ei-27g"/>
+                <outlet property="messageBackgroundView" destination="73U-Yu-hhb" id="JOP-eY-itl"/>
+                <outlet property="messageBgHeight" destination="9m9-a5-elu" id="8Ly-ju-XTf"/>
+                <outlet property="messageBgWidth" destination="B2b-ep-gRb" id="FSo-Zq-jds"/>
+                <outlet property="nameLabel" destination="O0d-aO-DEf" id="Mqt-5X-zmf"/>
+                <outlet property="timeLabel" destination="k0L-ig-bhB" id="ZJg-EA-Jw1"/>
+            </connections>
+            <point key="canvasLocation" x="57.971014492753625" y="111.49553571428571"/>
+        </tableViewCell>
+    </objects>
+</document>

+ 105 - 3
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageViewCell.swift

@@ -7,23 +7,125 @@
 //
 //
 
 
 import UIKit
 import UIKit
+import CocoaLumberjack
 
 
 class IMChatMessageViewCell: UITableViewCell {
 class IMChatMessageViewCell: UITableViewCell {
 
 
+    @IBOutlet weak var avatarImage: UIImageView!
     @IBOutlet weak var titleLabel: UILabel!
     @IBOutlet weak var titleLabel: UILabel!
+    @IBOutlet weak var timeLabel: UILabel!
+    @IBOutlet weak var messageBackgroundView: UIView!
+    @IBOutlet weak var messageBackgroundWidth: NSLayoutConstraint!
+    @IBOutlet weak var messageBackgroundHeight: NSLayoutConstraint!
+    private let messageWidth = 176
+    
     override func awakeFromNib() {
     override func awakeFromNib() {
         super.awakeFromNib()
         super.awakeFromNib()
-        // Initialization code
+        
     }
     }
 
 
     override func setSelected(_ selected: Bool, animated: Bool) {
     override func setSelected(_ selected: Bool, animated: Bool) {
         super.setSelected(selected, animated: animated)
         super.setSelected(selected, animated: animated)
-
         // Configure the view for the selected state
         // Configure the view for the selected state
     }
     }
     
     
     func setContent(item: IMMessageInfo) {
     func setContent(item: IMMessageInfo) {
-        self.titleLabel.text = item.createTime
+        //time
+        if let time = item.createTime {
+            let date = time.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
+            self.timeLabel.text = date.friendlyTime()
+        }
+        //name avatart
+        if let person = item.createPerson {
+            let urlstr = AppDelegate.o2Collect.generateURLWithAppContextKey(ContactContext.contactsContextKeyV2, query: ContactContext.personIconByNameQueryV2, parameter: ["##name##":person as AnyObject], generateTime: false)
+            if let u = URL(string: urlstr!) {
+                self.avatarImage.hnk_setImageFromURL(u)
+            }else {
+                self.avatarImage.image = UIImage(named: "icon_men")
+            }
+            //姓名
+            self.titleLabel.text = person.split("@").first ?? ""
+        }else {
+            self.avatarImage.image = UIImage(named: "icon_men")
+            self.titleLabel.text = ""
+        }
+        self.messageBackgroundView.removeSubviews()
+        if let jsonBody = item.body, let body = parseJson(msg: jsonBody) {
+            if body.type == o2_im_msg_type_emoji {
+                emojiMsgRender(emoji: body.body!)
+            }else {
+                textMsgRender(msg: body.body!)
+            }
+        }
+    }
+    
+    private func emojiMsgRender(emoji: String) {
+        let emojiSize = 36
+        let width = CGFloat(emojiSize + 20)
+        let height = CGFloat(emojiSize + 20)
+        self.messageBackgroundWidth.constant = width
+        self.messageBackgroundHeight.constant = height
+        //背景图片
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
+        let insets = UIEdgeInsets(top: 28, left: 10, bottom: 5, right: 5); // 上、左、下、右
+        var bubble = UIImage(named: "chat_bubble_incomming")
+        bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
+        bgImg.image = bubble
+        self.messageBackgroundView.addSubview(bgImg)
+        //表情图
+        let emojiImage = UIImageView(frame: CGRect(x: 0, y: 0, width: emojiSize, height: emojiSize))
+        let bundle = Bundle().o2EmojiBundle(anyClass: IMChatMessageViewCell.self)
+        let path = o2ImEmojiPath(emojiBody: emoji)
+        emojiImage.image = UIImage(named: path, in: bundle, compatibleWith: nil)
+        emojiImage.translatesAutoresizingMaskIntoConstraints = false
+        self.messageBackgroundView.addSubview(emojiImage)
+        let top = NSLayoutConstraint(item: emojiImage, attribute: .top, relatedBy: .equal, toItem: emojiImage.superview!, attribute: .top, multiplier: 1, constant: 10)
+        let bottom = NSLayoutConstraint(item: emojiImage.superview! , attribute: .bottom, relatedBy: .equal, toItem: emojiImage, attribute: .bottom, multiplier: 1, constant: 10)
+        let left = NSLayoutConstraint(item: emojiImage, attribute: .leading, relatedBy: .equal, toItem: emojiImage.superview!, attribute: .leading, multiplier: 1, constant: 10)
+        let right = NSLayoutConstraint(item: emojiImage.superview!, attribute: .trailing, relatedBy: .equal, toItem: emojiImage, attribute: .trailing, multiplier: 1, constant: 10)
+        NSLayoutConstraint.activate([top, bottom, left, right])
+    }
+    
+    private func textMsgRender(msg: String) {
+        let size = calTextSize(str: msg)
+        self.messageBackgroundWidth.constant = size.width + 20
+        self.messageBackgroundHeight.constant = size.height + 20
+        //背景图片
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 20, height: size.height + 20))
+        let insets = UIEdgeInsets(top: 28, left: 10, bottom: 5, right: 5); // 上、左、下、右
+        var bubble = UIImage(named: "chat_bubble_incomming")
+        bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
+        bgImg.image = bubble
+        self.messageBackgroundView.addSubview(bgImg)
+        //文字
+        let label = generateMessagelabel(str: msg, size: size)
+        label.translatesAutoresizingMaskIntoConstraints = false
+        self.messageBackgroundView.addSubview(label)
+        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
+//        let bottom = NSLayoutConstraint(item: label.superview! , attribute: .bottom, relatedBy: .equal, toItem: label, attribute: .bottom, multiplier: 1, constant: 10)
+        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
+        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
+        NSLayoutConstraint.activate([top, left, right])
     }
     }
     
     
+    private func generateMessagelabel(str: String, size: CGSize) -> UILabel {
+        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
+        label.text = str
+        label.font = UIFont.systemFont(ofSize: 16)
+        label.numberOfLines = 0
+        label.lineBreakMode = .byCharWrapping
+        label.preferredMaxLayoutWidth = size.width
+        return label
+    }
+    
+    
+    private func calTextSize(str: String) -> CGSize {
+        let size = CGSize(width: messageWidth.toCGFloat, height: CGFloat(MAXFLOAT))
+        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
+    }
+    
+    //解析json为消息对象
+    private func parseJson(msg: String) -> IMMessageBodyInfo? {
+        return IMMessageBodyInfo.deserialize(from: msg)
+    }
 }
 }

+ 55 - 12
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageViewCell.xib

@@ -10,32 +10,75 @@
     <objects>
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="IMChatMessageViewCell" customModule="O2Platform" customModuleProvider="target">
-            <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="132" id="KGk-i7-Jjw" customClass="IMChatMessageViewCell" customModule="O2Platform" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
-                <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
                 <subviews>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="111111" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2r2-Sl-HFm">
-                        <rect key="frame" x="12" y="8" width="296" height="28"/>
-                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Mov-YP-dlA">
+                        <rect key="frame" x="14" y="31" width="48" height="48"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="48" id="gOa-23-wjh"/>
+                            <constraint firstAttribute="width" constant="48" id="hMb-yE-x70"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="24"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </imageView>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="06-09 13:02" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fy3-Pu-FHB">
+                        <rect key="frame" x="14" y="5" width="292" height="18"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="18" id="c57-b5-RQY"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                        <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="姓名" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2r2-Sl-HFm">
+                        <rect key="frame" x="72" y="31" width="29" height="24"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="24" id="4T7-qw-JEB"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
                         <nil key="textColor"/>
                         <nil key="textColor"/>
                         <nil key="highlightedColor"/>
                         <nil key="highlightedColor"/>
                     </label>
                     </label>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jxc-0S-MrS">
+                        <rect key="frame" x="72" y="63" width="176" height="42"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="176" id="0aZ-iT-9wn"/>
+                            <constraint firstAttribute="height" constant="42" id="ah6-qa-1tp"/>
+                        </constraints>
+                    </view>
                 </subviews>
                 </subviews>
+                <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
                 <constraints>
                 <constraints>
-                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="45B-z7-I5v"/>
-                    <constraint firstAttribute="trailing" secondItem="2r2-Sl-HFm" secondAttribute="trailing" constant="12" id="YSs-xr-qNs"/>
-                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="12" id="mnz-Is-W7S"/>
-                    <constraint firstAttribute="bottom" secondItem="2r2-Sl-HFm" secondAttribute="bottom" constant="8" id="p9k-7p-IA8"/>
+                    <constraint firstItem="Mov-YP-dlA" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="0dz-GG-NKV"/>
+                    <constraint firstItem="fy3-Pu-FHB" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="33C-sl-5B1"/>
+                    <constraint firstItem="jxc-0S-MrS" firstAttribute="leading" secondItem="Mov-YP-dlA" secondAttribute="trailing" constant="10" id="3AB-04-3Ot"/>
+                    <constraint firstAttribute="trailing" secondItem="fy3-Pu-FHB" secondAttribute="trailing" constant="14" id="AQO-Yx-K4D"/>
+                    <constraint firstItem="Mov-YP-dlA" firstAttribute="top" secondItem="fy3-Pu-FHB" secondAttribute="bottom" constant="8" id="Faw-qG-7Fy"/>
+                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="top" secondItem="fy3-Pu-FHB" secondAttribute="bottom" constant="8" id="GtC-yx-sjT"/>
+                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="leading" secondItem="Mov-YP-dlA" secondAttribute="trailing" constant="10" id="JYE-0i-s5S"/>
+                    <constraint firstAttribute="bottomMargin" secondItem="jxc-0S-MrS" secondAttribute="bottom" constant="10" id="Tpo-I1-lKY"/>
+                    <constraint firstItem="fy3-Pu-FHB" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="5" id="VVF-dB-vnY"/>
+                    <constraint firstItem="jxc-0S-MrS" firstAttribute="top" secondItem="2r2-Sl-HFm" secondAttribute="bottom" constant="8" id="gYS-LW-7T4"/>
                 </constraints>
                 </constraints>
             </tableViewCellContentView>
             </tableViewCellContentView>
             <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
             <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
             <connections>
             <connections>
+                <outlet property="avatarImage" destination="Mov-YP-dlA" id="6a1-n4-fXG"/>
+                <outlet property="messageBackgroundHeight" destination="ah6-qa-1tp" id="hJ4-Xt-3Op"/>
+                <outlet property="messageBackgroundView" destination="jxc-0S-MrS" id="qTW-TG-fpN"/>
+                <outlet property="messageBackgroundWidth" destination="0aZ-iT-9wn" id="5UI-71-ADV"/>
+                <outlet property="timeLabel" destination="fy3-Pu-FHB" id="gvR-ts-fTh"/>
                 <outlet property="titleLabel" destination="2r2-Sl-HFm" id="kIP-0d-kYX"/>
                 <outlet property="titleLabel" destination="2r2-Sl-HFm" id="kIP-0d-kYX"/>
             </connections>
             </connections>
-            <point key="canvasLocation" x="132" y="139"/>
+            <point key="canvasLocation" x="131.8840579710145" y="94.419642857142847"/>
         </tableViewCell>
         </tableViewCell>
     </objects>
     </objects>
 </document>
 </document>

+ 1 - 1
o2ios/O2Platform/App/NewAttance-考勤打卡/m/OOAttandanceModels.swift

@@ -100,7 +100,7 @@ class OOAttandanceFeature: NSObject, DataModel {
     @objc var signDate: String?
     @objc var signDate: String?
     @objc var signTime: String?
     @objc var signTime: String?
     @objc var checkinType: String?
     @objc var checkinType: String?
-    var signSeq: Int?
+    var signSeq: Int? //第几次打卡 -1就不能打卡了
     
     
     required override init() {
     required override init() {
         
         

+ 2 - 2
o2ios/O2Platform/App/O2MainController.swift

@@ -89,8 +89,8 @@ class O2MainController: UITabBarController, UITabBarControllerDelegate {
 
 
     private func _initControllers() {
     private func _initControllers() {
         //消息
         //消息
-//        let conversationVC = JCConversationListViewController()
-        let conversationVC = IMConversationListViewController()
+        let conversationVC = JCConversationListViewController()
+//        let conversationVC = IMConversationListViewController()
         conversationVC.title = "消息"
         conversationVC.title = "消息"
         let messages = ZLNavigationController(rootViewController: conversationVC)
         let messages = ZLNavigationController(rootViewController: conversationVC)
 
 

+ 22 - 0
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_incomming.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "chat_bubble_incomming@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "chat_bubble_incomming@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_incomming.imageset/chat_bubble_incomming@2x.png


BIN
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_incomming.imageset/chat_bubble_incomming@3x.png


+ 22 - 0
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_outgoing.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "chat_bubble_outgoing@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "chat_bubble_outgoing@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_outgoing.imageset/chat_bubble_outgoing@2x.png


BIN
o2ios/O2Platform/Assets.xcassets/首页/chat_bubble_outgoing.imageset/chat_bubble_outgoing@3x.png