Copy/Transfer/Reply feature for chat messages

This commit is contained in:
Christophe Deschamps 2021-07-26 15:20:02 +02:00
parent b3a5168191
commit 0d55c0ca2f
49 changed files with 1396 additions and 564 deletions

View file

@ -1,17 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatConversationImdnView">
<connections>
<outlet property="msgAvatarImage" destination="LGG-kB-TaR" id="U4L-qV-ea2"/>
<outlet property="msgBackgroundColorImage" destination="wJQ-zl-d5O" id="D3d-vT-rFx"/>
<outlet property="msgBottomBar" destination="Mxm-1h-7dz" id="wS1-AL-B5M"/>
<outlet property="msgDateLabel" destination="jaE-4d-bbo" id="W3u-tE-pGo"/>
<outlet property="msgText" destination="V21-2s-obu" id="iTL-AZ-o7h"/>
<outlet property="msgView" destination="VK8-0e-Hsa" id="sWi-sR-kan"/>
<outlet property="tableView" destination="HjO-C8-Itr" id="cuC-QY-xbT"/>
<outlet property="view" destination="1g1-pp-Uhi" id="Km4-Mj-txf"/>
@ -19,19 +17,19 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1g1-pp-Uhi" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7Tm-Jz-Rvb">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X8x-9L-bCY" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Delivery status" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="bc0-Ql-lPE" userLabel="addressLabel">
<rect key="frame" x="112" y="0.0" width="150" height="66"/>
<rect key="frame" x="123" y="0.0" width="166" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
@ -41,7 +39,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JYS-Be-ffH" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -56,55 +54,21 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VK8-0e-Hsa" userLabel="msgView">
<rect key="frame" x="8" y="74" width="359" height="89"/>
<rect key="frame" x="8" y="74" width="398" height="123"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.20000000298023224" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="wJQ-zl-d5O" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="359" height="89"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="LGG-kB-TaR" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="7" y="7" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jaE-4d-bbo" userLabel="contactDateLabel">
<rect key="frame" x="55" y="8" width="279" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="Mxm-1h-7dz" userLabel="bottomBarColor">
<rect key="frame" x="0.0" y="88" width="359" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</imageView>
<textView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." translatesAutoresizingMaskIntoConstraints="NO" id="V21-2s-obu" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="52" y="29" width="296" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="HjO-C8-Itr">
<rect key="frame" x="8" y="171" width="359" height="496"/>
<rect key="frame" x="8" y="229" width="398" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="separatorColor" red="0.67030966280000004" green="0.71867996450000005" blue="0.75078284740000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -112,10 +76,14 @@
</view>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -31,6 +31,7 @@
<outlet property="pictureButton" destination="73" id="84"/>
<outlet property="popupMenu" destination="gdT-1Q-vU2" id="M7Q-tv-zRF"/>
<outlet property="portraitView" destination="6" id="xJJ-1H-6N6"/>
<outlet property="replyView" destination="wve-MK-7ME" id="fhJ-ne-9Xx"/>
<outlet property="sendButton" destination="15" id="27"/>
<outlet property="tableController" destination="29" id="32"/>
<outlet property="toggleMenuButton" destination="CPn-Oc-9PX" id="QdS-xO-bfA"/>
@ -387,6 +388,11 @@
<action selector="onEncryptedDevicesClick:" destination="-1" eventType="touchUpInside" id="K1W-Ao-IDg"/>
</connections>
</button>
<view hidden="YES" tag="290392" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wve-MK-7ME" userLabel="ReplyView">
<rect key="frame" x="0.0" y="536" width="414" height="120"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
</view>
<tableView hidden="YES" clipsSubviews="YES" tag="6992" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="gdT-1Q-vU2" userLabel="popupMenu">

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -10,6 +13,8 @@
<outlet property="addButton" destination="Z5G-IF-PBY" id="Tzw-rz-Bwe"/>
<outlet property="addGroupChatButton" destination="glf-ni-nqe" id="0hy-5m-7C7"/>
<outlet property="backToCallButton" destination="Fac-hy-za4" id="8I3-TM-oJ7"/>
<outlet property="cancelForwardButton" destination="Kxx-SO-CB0" id="LFJ-NQ-YrU"/>
<outlet property="forwardTitle" destination="waa-HU-xFW" id="Qqs-p4-k9A"/>
<outlet property="tableController" destination="4" id="18"/>
<outlet property="toggleSelectionButton" destination="uqG-2T-VOa" id="cAk-tz-5Z0"/>
<outlet property="view" destination="5" id="14"/>
@ -18,19 +23,19 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="WKv-mw-S2B" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<rect key="frame" x="0.0" y="42" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z5G-IF-PBY" userLabel="addButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -45,7 +50,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="glf-ni-nqe" userLabel="addGroupButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<rect key="frame" x="82" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -60,7 +65,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KhE-c3-2Zj" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -74,8 +79,22 @@
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="hKF-q1-5DJ"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Kxx-SO-CB0" userLabel="cancelForwardButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="cancel_forward.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelForwardClicked:" destination="-1" eventType="touchUpInside" id="2gp-RW-sJE"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fac-hy-za4" userLabel="backToCallButton" customClass="UIBackToCallButton">
<rect key="frame" x="150" y="0.0" width="75" height="66"/>
<rect key="frame" x="165" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -88,7 +107,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uqG-2T-VOa" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -104,7 +123,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxo-0W-iqY" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -118,7 +137,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qem-Y1-v78" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -133,12 +152,12 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="tableView">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
@ -146,31 +165,39 @@
<outlet property="delegate" destination="4" id="12"/>
</connections>
</tableView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="waa-HU-xFW" userLabel="forwardTitle">
<rect key="frame" x="0.0" y="66" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No conversations" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MSn-PY-yf1" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cpj-Jc-imm" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="559"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="DjR-Dv-uoX" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="267" width="20" height="20"/>
<rect key="frame" x="198" y="380" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="52" y="93.103448275862078"/>
<point key="canvasLocation" x="50.724637681159422" y="93.080357142857139"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="4" userLabel="tableController" customClass="ChatsListTableView">
<extendedEdge key="edgesForExtendedLayout"/>
@ -190,6 +217,7 @@
<image name="call_back_disabled.png" width="61.599998474121094" height="44"/>
<image name="cancel_edit_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_edit_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_forward.png" width="80" height="80"/>
<image name="chat_add_default.png" width="50.400001525878906" height="44.799999237060547"/>
<image name="chat_add_group.png" width="64" height="42.400001525878906"/>
<image name="color_E.png" width="2" height="2"/>
@ -198,5 +226,11 @@
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -36,13 +36,11 @@
@property(nonatomic) bctbx_list_t *receivedList;
@property(nonatomic) bctbx_list_t *notReceivedList;
@property(nonatomic) bctbx_list_t *errorList;
@property(nonatomic) UIChatBubbleTextCell *cell;
@property(nonatomic) NSTimer *ephemeralDisplayTimer;
@property (weak, nonatomic) IBOutlet UIView *msgView;
@property (weak, nonatomic) IBOutlet UIImageView *msgBackgroundColorImage;
@property (weak, nonatomic) IBOutlet UIRoundedImageView *msgAvatarImage;
@property (weak, nonatomic) IBOutlet UIImageView *msgBottomBar;
@property (weak, nonatomic) IBOutlet UILabel *msgDateLabel;
@property (weak, nonatomic) IBOutlet UITextViewNoDefine *msgText;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
- (IBAction)onBackClick:(id)sender;

View file

@ -22,6 +22,7 @@
#import "ChatConversationImdnView.h"
#import "PhoneMainView.h"
#import "UIChatBubbleTextCell.h"
#import "UIChatBubblePhotoCell.h"
#import "UIChatConversationImdnTableViewCell.h"
@implementation ChatConversationImdnView
@ -52,21 +53,40 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
const LinphoneAddress *addr = linphone_chat_message_get_from_address(_msg);
BOOL outgoing = linphone_chat_message_is_outgoing(_msg);
_msgDateLabel.text = [NSString stringWithFormat:@"%@ - %@",
[LinphoneUtils timeToString:linphone_chat_message_get_time(_msg) withFormat:LinphoneDateChatBubble],
[FastAddressBook displayNameForAddress:addr]];
_msgAvatarImage.image = outgoing ? [LinphoneUtils selfAvatar] : [FastAddressBook imageForAddress:addr];
_msgText.text = messageText;
_msgBackgroundColorImage.image = _msgBottomBar.image = [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")];
_msgDateLabel.textColor = [UIColor colorWithPatternImage:_msgBackgroundColorImage.image];
int index = [VIEW(ChatConversationView).tableController indexOfMesssage:_msg];
if (index < 0)
[PhoneMainView.instance popToView:ChatConversationView.compositeViewDescription];
_cell = (UIChatBubbleTextCell *)[VIEW(ChatConversationView).tableController tableView:VIEW(ChatConversationView).tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
_cell.frame = CGRectMake(-10,0,_msgView.frame.size.width,_msgView.frame.size.height);
_cell.isFirst = true;
_cell.isLast = true;
[_cell update];
_cell.popupMenuAllowed = false;
for (UIView *v in [_msgView subviews]) {
[v removeFromSuperview];
}
[_msgView addSubview:_cell];
_tableView.delegate = self;
_tableView.dataSource = self;
[self updateImdnList];
[self fitContent];
[self startEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(ephemeralDeleted:)
name:kLinphoneEphemeralMessageDeletedInRoom
object:nil];
}
-(void) viewWillDisappear:(BOOL)animated {
[self stopEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter removeObserver:self];
[super viewWillDisappear:animated];
}
- (void)updateImdnList {
@ -81,15 +101,12 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)fitContent {
[self setMessageText];
BOOL outgoing = linphone_chat_message_is_outgoing(_msg);
_msgBackgroundColorImage.image = _msgBottomBar.image = [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")];
_msgDateLabel.textColor = [UIColor colorWithPatternImage:_msgBackgroundColorImage.image];
CGSize messageSize = [UIChatBubbleTextCell ViewHeightForMessage:_msg withWidth:self.view.frame.size.width];
[_msgView setFrame:CGRectMake(_msgView.frame.origin.x,
_msgView.frame.origin.y,
_msgView.frame.size.width,
[UIChatBubbleTextCell ViewHeightForMessageText:_msg withWidth:self.view.frame.size.width textForImdn:messageText].height)];
self.view.frame.size.width,
messageSize.height+5)];
[_tableView setFrame:CGRectMake(_tableView.frame.origin.x,
_msgView.frame.origin.y + _msgView.frame.size.height + 10,
@ -101,18 +118,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[self fitContent];
}
- (void)setMessageText {
const char *utf8Text= linphone_chat_message_get_text_content(_msg);
LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(_msg);
messageText = nil;
if (utf8Text) {
messageText = [NSString stringWithUTF8String:utf8Text];
if (fileContent)
messageText = [NSString stringWithFormat:@"%@\n%@", messageText, [NSString stringWithUTF8String: linphone_content_get_name(fileContent)]];
} else {
messageText = [NSString stringWithUTF8String: linphone_content_get_name(fileContent)];
}
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
@ -278,4 +284,38 @@ static UICompositeViewDescription *compositeDescription = nil;
[PhoneMainView.instance popCurrentView];
}
#pragma mark ephemeral messages
-(void) startEphemeralDisplayTimer {
_ephemeralDisplayTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateEphemeralTimes)
userInfo:nil
repeats:YES];
}
-(void) updateEphemeralTimes {
NSDateComponentsFormatter *f= [[NSDateComponentsFormatter alloc] init];
f.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
f.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
if (linphone_chat_message_is_ephemeral(_msg)) {
long duration = linphone_chat_message_get_ephemeral_expire_time(_msg) == 0 ?
linphone_chat_room_get_ephemeral_lifetime(linphone_chat_message_get_chat_room(_msg)) :
linphone_chat_message_get_ephemeral_expire_time(_msg)-[NSDate date].timeIntervalSince1970;
f.allowedUnits = (duration > 86400 ? kCFCalendarUnitDay : 0)|(duration > 3600 ? kCFCalendarUnitHour : 0)|kCFCalendarUnitMinute|kCFCalendarUnitSecond;
_cell.ephemeralTime.text = [f stringFromTimeInterval:duration];
_cell.ephemeralTime.hidden = NO;
_cell.ephemeralIcon.hidden = NO;
}
}
-(void) stopEphemeralDisplayTimer {
[_ephemeralDisplayTimer invalidate];
}
- (void)ephemeralDeleted:(NSNotification *)notif {
[PhoneMainView.instance popToView:ChatConversationView.compositeViewDescription];
}
@end

View file

@ -39,10 +39,10 @@
@protocol ChatConversationDelegate <NSObject>
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message voiceContent:(LinphoneContent *)voiceContent;
- (BOOL)resendFile:(NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message voiceContent:(LinphoneContent *)voiceContent;
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name;
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url voiceContent:(LinphoneContent *)voiceContent;
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage;
- (BOOL)resendFile:(NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage;
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)tableViewIsScrolling;
@end
@ -64,5 +64,9 @@
- (void)scrollToLastUnread:(BOOL)animated;
- (void)updateEventEntry:(LinphoneEventLog *)event;
- (void)refreshData;
- (void)reloadData;
- (void) dismissMessagesPopups;
- (void) scrollToMessage:(LinphoneChatMessage *)message;
- (int) indexOfMesssage:(LinphoneChatMessage *)message;
@end

View file

@ -49,6 +49,7 @@
}
-(void) viewWillDisappear:(BOOL)animated {
[self dismissMessagesPopups];
[self stopEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter removeObserver:self];
[super viewWillDisappear:animated];
@ -204,6 +205,39 @@
animated:animated];
}
- (void) scrollToMessage:(LinphoneChatMessage *)message {
int index = [self indexOfMesssage:message];
if (index < 0)
return;
[self.tableView.layer removeAllAnimations];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:true];
}
-(int) indexOfMesssage:(LinphoneChatMessage *)message {
if (eventList.count == 0 || _chatRoom == nil)
return -1;
int index = -1;
size_t count = eventList.count;
for (int i = (int)count - 1; i > 0; --i) {
LinphoneEventLog *event = [[eventList objectAtIndex:i] pointerValue];
if (!(linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage))
continue;;
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
if (chat == message) {
index = i;
break;
}
}
return index;
}
#pragma mark - Property Functions
- (void)setChatRoom:(LinphoneChatRoom *)room {
@ -275,6 +309,15 @@ static const int BASIC_EVENT_LIST=15;
if (!_chatRoom && [[cell reuseIdentifier] isEqualToString:@"UIChatBubblePhotoCell"]) {
[(UIChatBubbleTextCell *)cell clearEncryptedFiles];
}
if ([cell isKindOfClass:[UIChatBubbleTextCell class]] ||[cell isKindOfClass:[UIChatBubblePhotoCell class]])
[(UIChatBubbleTextCell *)cell dismissPopup];
}
-(void) dismissMessagesPopups {
for (UITableViewCell *cell in self.tableView.visibleCells) {
if (![[cell reuseIdentifier] isEqualToString:NSStringFromClass(UIChatNotifiedEventCell.class)])
[(UIChatBubbleTextCell *)cell dismissPopup];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -301,6 +344,8 @@ static const int BASIC_EVENT_LIST=15;
[cell setChatRoomDelegate:_chatRoomDelegate];
[super accessoryForCell:cell atPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.tableController = self;
cell.popupMenuAllowed = true;
return cell;
} else {
kCellId = NSStringFromClass(UIChatNotifiedEventCell.class);
@ -393,6 +438,8 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
if (linphone_event_log_get_chat_message(event)) {
linphone_chat_room_delete_message(_chatRoom, linphone_event_log_get_chat_message(event));
} else {
linphone_event_log_delete_from_database(event);
}
NSInteger index = indexPath.row + _currentIndex + (totalEventList.count - eventList.count);
if (index < totalEventList.count)

View file

@ -32,7 +32,8 @@
#import "UIImageViewDeletable.h"
#import "UIConfirmationDialog.h"
#import "UIInterfaceStyleButton.h"
#import "linphoneapp-Swift.h"
#import "UIChatReplyBubbleView.h"
#include "linphone/linphonecore.h"
@ -111,7 +112,15 @@
@property LinphoneRecorder *voiceRecorder;
@property LinphonePlayer *sharedVoicePlayer;
@property BOOL showVoiceRecorderView;
@property BOOL preservePendingRecording;
@property BOOL preservePendingActions;
// Reply
@property (weak, nonatomic) IBOutlet UIView *replyView;
@property BOOL showReplyView;
@property UIChatReplyBubbleView *replyBubble;
// Forward
@property LinphoneChatMessage *pendingForwardMessage;
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom;
@ -149,4 +158,6 @@
-(void) stopSharedPlayer;
-(BOOL) sharedPlayedIsPlaying:(const char *)path;
-(void) initiateReplyViewForMessage:(LinphoneChatMessage *)message;
@end

View file

@ -137,7 +137,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
tabBar:nil
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
@ -258,7 +258,7 @@ static UICompositeViewDescription *compositeDescription = nil;
CGRect tableViewFrame = [_tableController.tableView frame];
tableViewFrame.size.height -= 120;
[_tableController.tableView setFrame:tableViewFrame];
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
}
completion:nil];
}
@ -269,17 +269,26 @@ static UICompositeViewDescription *compositeDescription = nil;
popupFrame.size.height = 44 * [_popupMenu numberOfRowsInSection:0];
_popupMenu.frame = popupFrame;
// Voice recording
// Voice recording & Replies
_vrView.hidden = true;
_preservePendingRecording = false;
_toggleRecord.enabled = linphone_core_get_calls_nb(LC) == 0;
_replyView.hidden = true;
_preservePendingActions = false;
_toggleRecord.enabled = linphone_core_get_calls_nb(LC) == 0;
}
- (void)viewWillDisappear:(BOOL)animated {
if (!_preservePendingRecording)
if (!_preservePendingActions)
[self cancelVoiceRecording];
if (!_preservePendingActions)
[self closePendingReply];
else if (_isVoiceRecording)
[self stopVoiceRecording];
@ -330,10 +339,14 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark -
- (void)applicationWillEnterBackground{
if (!_preservePendingRecording)
if (!_preservePendingActions)
[self cancelVoiceRecording];
else if (_isVoiceRecording)
[self stopVoiceRecording];
if (!_preservePendingActions)
[self closePendingReply];
[self stopAllPlays];
}
@ -393,6 +406,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[self setupPopupMenu];
_ephemeralndicator.hidden = !linphone_chat_room_ephemeral_enabled(_chatRoom);
}
[self handlePendingTransferIfAny];
}
@ -420,7 +434,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
-(NSData *) nsDataRead {
NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]];
NSString* groupName = @"group.com.clavys.frogtrust.store";
NSString *path =[[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupName] path];
NSString *fullCacheFilePathPath = [NSString stringWithFormat:@"%@/%@",path,@"nsData"];
return[NSData dataWithContentsOfFile:fullCacheFilePathPath];
@ -428,7 +442,8 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)shareFile {
NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]];
NSString* groupName = @"group.com.clavys.frogtrust.store";
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
NSDictionary *dict = [defaults valueForKey:@"photoData"];
@ -505,13 +520,13 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL *)externalUrl andVoiceContent:(LinphoneContent *)voiceContent {
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL *)externalUrl rootMessage:(LinphoneChatMessage *)rootMessage {
if (_chatRoom == NULL) {
LOGW(@"Cannot send message: No chatroom");
return FALSE;
}
LinphoneChatMessage *msg = linphone_chat_room_create_empty_message(_chatRoom);
LinphoneChatMessage *msg = rootMessage;
if (message && message.length > 0)
linphone_chat_message_add_utf8_text_content(msg, message.UTF8String);
@ -519,11 +534,6 @@ static UICompositeViewDescription *compositeDescription = nil;
linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]);
}
// Voice recording
if (voiceContent)
linphone_chat_message_add_content(msg, voiceContent);
// we must ref & unref message because in case of error, it will be destroy otherwise
linphone_chat_message_send(msg);
@ -566,15 +576,15 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)confirmShare:(NSData *)data url:(NSString *)url fileName:(NSString *)fileName {
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:@""];
dispatch_async(dispatch_get_main_queue(), ^{
[sheet addButtonWithTitle:NSLocalizedString(@"Send to this friend", nil)
[sheet addButtonWithTitle:NSLocalizedString(@"send to this conversation", nil)
block:^() {
if (![[self.messageField text] isEqualToString:@""]) {
[self sendMessageInMessageFieldWithVoiceContent:nil];
[self sendMessageInMessageField:linphone_chat_room_create_empty_message(_chatRoom)];
}
if (url)
[self sendMessage:url withExterlBodyUrl:nil andVoiceContent:nil];
[self sendMessage:url withExterlBodyUrl:nil rootMessage:linphone_chat_room_create_empty_message(_chatRoom)];
else
[self startFileUpload:data withName:fileName];
[self startFileUpload:data withName:fileName rootMessage:linphone_chat_room_create_empty_message(_chatRoom)];
}];
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
@ -657,8 +667,8 @@ static UICompositeViewDescription *compositeDescription = nil;
_addressLabel.frame = frame;
}
- (void)sendMessageInMessageFieldWithVoiceContent:(LinphoneContent *)voiceContent {
if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil andVoiceContent:voiceContent]) {
- (void)sendMessageInMessageField:(LinphoneChatMessage *)rootMessage {
if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil rootMessage:rootMessage]) {
scrollOnGrowingEnabled = FALSE;
[_messageField setText:@""];
scrollOnGrowingEnabled = TRUE;
@ -714,7 +724,7 @@ static UICompositeViewDescription *compositeDescription = nil;
CGRect tableRect = [_tableController.view frame];
tableRect.size.height -= diff;
[_tableController.view setFrame:tableRect];
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
// if we're showing the compose message, update it position
if (![_composeLabel isHidden]) {
@ -739,40 +749,48 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (IBAction)onSendClick:(id)event {
LinphoneContent *voiceContent = nil;
if (!linphone_core_is_network_reachable(LC)) {
//[PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView:@"send a message"] animated:YES completion:nil];
//return;
}
LinphoneChatMessage *rootMessage = _replyBubble ? linphone_chat_room_create_reply_message(_chatRoom, _replyBubble.message) : linphone_chat_room_create_empty_message(_chatRoom);
if (_replyBubble) {
[self closePendingReply];
}
if (_isPendingVoiceRecord && _voiceRecorder && linphone_recorder_get_file(_voiceRecorder)) {
voiceContent = linphone_recorder_create_content(_voiceRecorder);
LinphoneContent * voiceContent = linphone_recorder_create_content(_voiceRecorder);
_isPendingVoiceRecord = false;
[self cancelVoiceRecording];
[self stopVoiceRecordPlayer];
linphone_chat_message_add_content(rootMessage, voiceContent);
}
if (!linphone_core_is_network_reachable(LC)) {
[PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView:@"send a message"] animated:YES completion:nil];
return;
}
if ([_fileContext count] > 0) {
if (linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesConference) {
[self startMultiFilesUploadWithVoiceContent:voiceContent];
[self startMultiFilesUpload:rootMessage];
} else {
int i = 0;
for (i = 0; i < [_fileContext count]-1; ++i) {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL voiceContent:voiceContent];
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL rootMessage:rootMessage];
}
if (isOneToOne) {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL voiceContent:voiceContent];
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL rootMessage:rootMessage];
if (![[self.messageField text] isEqualToString:@""]) {
[self sendMessage:[_messageField text] withExterlBodyUrl:nil andVoiceContent:voiceContent];
[self sendMessage:[_messageField text] withExterlBodyUrl:nil rootMessage:rootMessage];
}
} else {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:[self.messageField text] voiceContent:voiceContent];
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:[self.messageField text] rootMessage:rootMessage];
}
}
[self clearMessageView];
return;
}
[self sendMessageInMessageFieldWithVoiceContent:voiceContent];
[self sendMessageInMessageField:rootMessage];
}
- (IBAction)onListTap:(id)sender {
@ -833,7 +851,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (IBAction)onPictureClick:(id)event {
_preservePendingRecording = true;
_preservePendingActions = true;
[_messageField resignFirstResponder];
[ImagePickerView SelectImageFromDevice:self atPosition:_pictureButton inView:self.view withDocumentMenuDelegate:self];
@ -867,15 +885,15 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark ChatRoomDelegate
- (BOOL)startMultiFilesUploadWithVoiceContent:(LinphoneContent *)voiceContent {
- (BOOL)startMultiFilesUpload:(LinphoneChatMessage *)rootMessage {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
[fileTransfer setText:[self.messageField text]];
[fileTransfer uploadFileContent:_fileContext forChatRoom:_chatRoom andVoiceContent:voiceContent];
[fileTransfer uploadFileContent:_fileContext forChatRoom:_chatRoom rootMessage:rootMessage];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)startUploadData:(NSData *)data withType:(NSString*)type withName:(NSString *)name andMessage:(NSString *)message voiceContent:(LinphoneContent *)voiceContent {
- (BOOL)startUploadData:(NSData *)data withType:(NSString*)type withName:(NSString *)name andMessage:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
[fileTransfer setText:message];
@ -885,38 +903,38 @@ static UICompositeViewDescription *compositeDescription = nil;
} else if ([type isEqualToString:@"image"]) {
key = @"localimage";
}
[fileTransfer uploadData:data forChatRoom:_chatRoom type:type subtype:type name:name key:key voiceContent:voiceContent];
[fileTransfer uploadData:data forChatRoom:_chatRoom type:type subtype:type name:name key:key rootMessage:rootMessage];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name {
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name rootMessage:(LinphoneChatMessage *)rootMessage {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
[fileTransfer uploadFile:data forChatRoom:_chatRoom withName:name];
[fileTransfer uploadFile:data forChatRoom:_chatRoom withName:name rootMessage:rootMessage];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message voiceContent:(LinphoneContent *)voiceContent {
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
[fileTransfer setText:message];
[fileTransfer uploadFileContent:newFileContext forChatRoom:_chatRoom andVoiceContent:voiceContent];
[fileTransfer uploadFileContent:newFileContext forChatRoom:_chatRoom rootMessage:rootMessage];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)resendFile: (NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message voiceContent:(LinphoneContent *)voiceContent{
- (BOOL)resendFile: (NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage{
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
[fileTransfer setText:message];
[fileTransfer uploadData:data forChatRoom:_chatRoom type:type subtype:type name:name key:key voiceContent:voiceContent];
[fileTransfer uploadData:data forChatRoom:_chatRoom type:type subtype:type name:name key:key rootMessage:rootMessage];
[_tableController scrollToBottom:true];
return TRUE;
}
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url voiceContent:(LinphoneContent *)voiceContent {
[self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] andVoiceContent:voiceContent];
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url rootMessage:(LinphoneChatMessage *)rootMessage {
[self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] rootMessage:rootMessage];
}
#pragma mark ImagePickerDelegate
@ -1171,8 +1189,10 @@ static UICompositeViewDescription *compositeDescription = nil;
[_tableController.tableView setFrame:tableViewFrame];
}
if (_showVoiceRecorderView)
_vrView.hidden = true;
[self updateFramesInclRecordingView];
_vrView.hidden = true; // force recalculate
if (_showReplyView)
_replyView.hidden = true; // force recalculate
[self updateFramesInclRecordingAndReplyView];
}
completion:^(BOOL finished){
@ -1257,8 +1277,10 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
if (_showVoiceRecorderView)
_vrView.hidden = true;
[self updateFramesInclRecordingView];
_vrView.hidden = true; // force recalculate
if (_showReplyView)
_replyView.hidden = true; // force recalculate
[self updateFramesInclRecordingAndReplyView];
}
@ -1497,7 +1519,7 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
CGRect tableViewFrame = [_tableController.tableView frame];
tableViewFrame.size.height = imagesFrame.origin.y - tableViewFrame.origin.y;
[_tableController.tableView setFrame:tableViewFrame];
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
}
completion:nil];
[self setSendButtonState];
@ -1511,7 +1533,7 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
CGRect tableViewFrame = [_tableController.tableView frame];
tableViewFrame.size.height = imagesFrame.origin.y - tableViewFrame.origin.y;
[_tableController.tableView setFrame:tableViewFrame];
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
[_imagesCollectionView reloadData];
}
}
@ -1705,13 +1727,12 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
LinphoneRecorderParams *p = linphone_core_create_recorder_params(LC);
linphone_recorder_params_set_file_format(p, LinphoneRecorderFileFormatWav);
_voiceRecorder = linphone_core_create_recorder(LC, p);
[CallManager.instance activateAudioSession];
}
-(void) cancelVoiceRecording {
_showVoiceRecorderView = false;
_toggleRecord.selected = false;
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
_isPendingVoiceRecord = false;
_isVoiceRecording = false;
if (_voiceRecorder && linphone_recorder_get_state(_voiceRecorder) != LinphoneRecorderClosed) {
@ -1748,13 +1769,13 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
if (!_voiceRecorder)
[self createVoiceRecorder];
[CallManager.instance activateAudioSession];
_toggleRecord.selected = true;
[_vrPlayButton setImage:[UIImage imageNamed:@"vr_stop"] forState:UIControlStateNormal];
_showVoiceRecorderView = true;
[self updateFramesInclRecordingView];
[self updateFramesInclRecordingAndReplyView];
_isVoiceRecording = true;
_vrWaveMaskPlayer.frame = CGRectZero;
@ -1850,9 +1871,6 @@ void on_shared_player_eof_reached(LinphonePlayer *p) {
NSDictionary* userInfo = @{@"path": [NSString stringWithUTF8String:currentPlayedFile]};
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneVoiceMessagePlayerEOF object:nil userInfo:userInfo];
}
// ChatConversationView *view = (__bridge ChatConversationView *)linphone_player_cbs_get_user_data(linphone_player_get_current_callbacks(p));
// [view stopVoiceRecordPlayer];
}
// Playback of new recordings
@ -1907,20 +1925,35 @@ void on_shared_player_eof_reached(LinphonePlayer *p) {
return [NSString stringWithFormat:@"%02ld:%02ld", valueMs/ 60000, (valueMs % 60000) / 1000 ];
}
-(void) updateFramesInclRecordingView { // place below the messages table.
BOOL showHide = _showVoiceRecorderView != !_vrView.hidden;
if (showHide)
-(void) updateFramesInclRecordingAndReplyView { // place below the messages table.
BOOL showHideVoice = _showVoiceRecorderView != !_vrView.hidden;
if (showHideVoice)
_vrView.hidden = !_showVoiceRecorderView;
CGRect vrFrame = _vrView.frame;
CGRect tableFrame = _tableController.tableView.frame;
if (showHide) {
if (showHideVoice) {
tableFrame.size.height = _showVoiceRecorderView ? tableFrame.size.height - vrFrame.size.height : tableFrame.size.height + vrFrame.size.height;
_tableController.tableView.frame = tableFrame;
[_tableController.tableView reloadData];
}
vrFrame.origin.y = tableFrame.origin.y+tableFrame.size.height;
_vrView.frame = vrFrame;
BOOL showHideReply = _showReplyView != !_replyView.hidden;
if (showHideReply)
_replyView.hidden = !_showReplyView;
CGRect repFrame = _replyView.frame;
tableFrame = _tableController.tableView.frame;
if (showHideReply) {
tableFrame.size.height = _showReplyView ? tableFrame.size.height - repFrame.size.height : tableFrame.size.height + repFrame.size.height;
_tableController.tableView.frame = tableFrame;
[_tableController.tableView reloadData];
}
repFrame.origin.y = _showVoiceRecorderView ? vrFrame.origin.y + vrFrame.size.height : tableFrame.origin.y+tableFrame.size.height;
_replyView.frame = repFrame;
}
-(void) stopAllPlays {
@ -1937,5 +1970,48 @@ void on_shared_player_eof_reached(LinphonePlayer *p) {
}
// Reply
-(void) closePendingReply {
if (_replyBubble != nil) {
_showReplyView = false;
[_replyBubble.view removeFromSuperview];
[self updateFramesInclRecordingAndReplyView];
_replyBubble = nil;
}
}
-(void) initiateReplyViewForMessage:(LinphoneChatMessage *)message {
if (_replyBubble != nil)
[self closePendingReply];
_replyBubble = [[UIChatReplyBubbleView alloc] initWithNibName:@"UIChatReplyBubbleView" bundle:nil];
[self addChildViewController:_replyBubble];
[_replyView addSubview:_replyBubble.view];
[_replyBubble didMoveToParentViewController:self];
[_replyBubble configureForMessage:message withDimissBlock:^{
[self closePendingReply];
} hideDismiss:false withClickBlock:^{}];
_showReplyView = true;
[self updateFramesInclRecordingAndReplyView];
[self.tableController scrollToMessage:message];
}
-(void) handlePendingTransferIfAny {
if (self.pendingForwardMessage) {
LinphoneChatMessage *message = self.pendingForwardMessage;
self.pendingForwardMessage = nil;
UIConfirmationDialog *d = [UIConfirmationDialog ShowWithMessage:NSLocalizedString(@"Transfer this message to this conversation ?",nil)
cancelMessage:nil
confirmMessage:NSLocalizedString(@"TRANSFER",nil)
onCancelClick:^() {}
onConfirmationClick:^() {
linphone_chat_message_send(linphone_chat_room_create_forward_message(_chatRoom, message));
}];
d.forwardImage.hidden = NO;
[d setSpecialColor];
}
}
@end

View file

@ -28,6 +28,7 @@
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property bctbx_list_t *data;
- (void)loadData;
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom;
@end

View file

@ -160,6 +160,13 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
[cell setChatRoom:(LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row])];
[super accessoryForCell:cell atPath:indexPath];
BOOL forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
cell.forwardIcon.hidden = !forwardMode;
if (forwardMode) {
cell.ephemeral.hidden = true;
cell.imdmIcon.hidden = true;
}
return cell;
}

View file

@ -34,6 +34,9 @@
@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleSelectionButton;
@property (weak, nonatomic) IBOutlet UILabel *forwardTitle;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *cancelForwardButton;
- (IBAction)onAddGroupChatClick:(id)event;
- (IBAction)onAddClick:(id)event;

View file

@ -53,8 +53,28 @@
[button addTarget:self action:@selector(crashButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];*/
BOOL forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
_tableController.editButton.hidden = forwardMode;
_forwardTitle.text = NSLocalizedString(@"Select a discussion or create a new one",nil);
_forwardTitle.hidden = !forwardMode;
_cancelForwardButton.hidden = !forwardMode;
_tableController.tableView.frame = CGRectMake(0, 66 + (forwardMode ? _forwardTitle.frame.size.height : 0), _tableController.tableView.frame.size.width, self.view.frame.size.height - 66 - ( forwardMode ? _forwardTitle.frame.size.height : 0 ));
_addButton.frame = CGRectMake(forwardMode ? 82 : 0 , _addButton.frame.origin.y, _addButton.frame.size.width, _addButton.frame.size.height);
_addGroupChatButton.frame = CGRectMake(forwardMode ? 164 : 82 , _addGroupChatButton.frame.origin.y, _addGroupChatButton.frame.size.width, _addGroupChatButton.frame.size.height);
}
- (void)ephemeralDeleted:(NSNotification *)notif {
//LinphoneChatRoom *r =[[notif.userInfo objectForKey:@"room"] intValue];
[self.tableController loadData];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
@ -150,8 +170,9 @@ static UICompositeViewDescription *compositeDescription = nil;
assert(NO);
}
- (void)ephemeralDeleted:(NSNotification *)notif {
[self.tableController loadData];
- (IBAction)onCancelForwardClicked:(id)sender {
VIEW(ChatConversationView).pendingForwardMessage = nil;
[PhoneMainView.instance popCurrentView];
}
@end

View file

@ -29,9 +29,10 @@
<outlet property="innerView" destination="Y7i-Gm-AdY" id="PbL-8X-8Fi"/>
<outlet property="messageImageView" destination="yMW-cT-bpU" id="MNr-F2-abQ"/>
<outlet property="messageText" destination="cx9-0K-P9L" id="kPh-s4-Ioy"/>
<outlet property="photoCellContentView" destination="VAJ-tE-fsa" id="JXg-8d-aCi"/>
<outlet property="playButton" destination="cvc-tl-Pcf" id="eKJ-2T-LUl"/>
<outlet property="plusLongGestureRecognizer" destination="daf-cW-dRj" id="O5u-t0-uMe"/>
<outlet property="resendRecognizer" destination="5ZI-Ip-lGl" id="G2r-On-6mV"/>
<outlet property="replyTransferIcon" destination="DFk-Mg-EnD" id="gPH-xU-mAw"/>
<outlet property="replyTransferLabel" destination="l8e-ta-Fv5" id="9Ns-ZN-Wbl"/>
<outlet property="totalView" destination="8I3-n2-0kS" id="aa8-j9-saW"/>
<outlet property="vrPlayPause" destination="7Zn-bp-e0Y" id="ed8-ZL-VpS"/>
<outlet property="vrTimerLabel" destination="VUD-m6-g1J" id="tOj-bF-YHd"/>
@ -65,163 +66,179 @@
<rect key="frame" x="39" y="20" width="382" height="357"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Répondu" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l8e-ta-Fv5" userLabel="replyTransferLabel">
<rect key="frame" x="17" y="3" width="69" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="menu_reply_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="DFk-Mg-EnD" userLabel="replyTransferIcon">
<rect key="frame" x="3" y="3" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" alpha="0.20000000298023224" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="U2P-5n-gg8" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="365" height="357"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8I3-n2-0kS" userLabel="view">
<rect key="frame" x="27" y="10" width="301" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VAJ-tE-fsa">
<rect key="frame" x="0.0" y="10" width="382" height="347"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="linphone_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="yMW-cT-bpU" userLabel="image" customClass="UILoadingImageView">
<rect key="frame" x="0.0" y="0.0" width="301" height="161"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<gestureRecognizers/>
</imageView>
</subviews>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VYJ-RC-Jmg" userLabel="finalAssetView">
<rect key="frame" x="7" y="10" width="351" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gzv-K4-5OL" userLabel="finalImage">
<rect key="frame" x="0.0" y="0.0" width="351" height="262"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<gestureRecognizers/>
</imageView>
</subviews>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UzU-cc-LbF" userLabel="fileView">
<rect key="frame" x="13" y="10" width="230" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WkE-rP-Y0R" userLabel="fileName">
<rect key="frame" x="0.0" y="0.0" width="180" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IGl-nl-xIE" userLabel="fileButton">
<rect key="frame" x="180" y="0.0" width="50" height="50"/>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8I3-n2-0kS" userLabel="view">
<rect key="frame" x="27" y="0.0" width="301" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="linphone_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="yMW-cT-bpU" userLabel="image" customClass="UILoadingImageView">
<rect key="frame" x="0.0" y="0.0" width="301" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<gestureRecognizers/>
</imageView>
</subviews>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VYJ-RC-Jmg" userLabel="finalAssetView">
<rect key="frame" x="7" y="0.0" width="351" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gzv-K4-5OL" userLabel="finalImage">
<rect key="frame" x="0.0" y="0.0" width="351" height="262"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<gestureRecognizers/>
</imageView>
</subviews>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UzU-cc-LbF" userLabel="fileView">
<rect key="frame" x="13" y="0.0" width="230" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="0.39905477280000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Open"/>
<connections>
<action selector="onFileClick:" destination="-1" eventType="touchUpInside" id="JRN-AA-UEJ"/>
</connections>
</button>
</subviews>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GmN-7v-uuO" userLabel="imageSubView">
<rect key="frame" x="31" y="50" width="299" height="87"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" fixedFrame="YES" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="USm-wC-GvG" userLabel="transferProgress">
<rect key="frame" x="10" y="51" width="277" height="4"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</progressView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Download"/>
<state key="normal" title="DOWNLOAD" backgroundImage="color_G.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onDownloadClick:" destination="-1" eventType="touchUpInside" id="8BO-9E-iOX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WkE-rP-Y0R" userLabel="fileName">
<rect key="frame" x="0.0" y="0.0" width="180" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IGl-nl-xIE" userLabel="fileButton">
<rect key="frame" x="180" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="0.39905477280000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Open"/>
<connections>
<action selector="onFileClick:" destination="-1" eventType="touchUpInside" id="JRN-AA-UEJ"/>
</connections>
</button>
</subviews>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GmN-7v-uuO" userLabel="imageSubView">
<rect key="frame" x="31" y="40" width="299" height="87"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" fixedFrame="YES" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="USm-wC-GvG" userLabel="transferProgress">
<rect key="frame" x="10" y="51" width="277" height="4"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</progressView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Download"/>
<state key="normal" title="DOWNLOAD" backgroundImage="color_G.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onDownloadClick:" destination="-1" eventType="touchUpInside" id="8BO-9E-iOX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="CANCEL" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="D9y-vf-I4Y"/>
</connections>
</button>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cvc-tl-Pcf" userLabel="playButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="157" y="96" width="50" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="CANCEL" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="PLAY" backgroundImage="color_I.png">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="D9y-vf-I4Y"/>
<action selector="onPlayClick:" destination="-1" eventType="touchUpInside" id="B4y-PJ-4tO"/>
</connections>
</button>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cvc-tl-Pcf" userLabel="playButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="157" y="106" width="50" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="PLAY" backgroundImage="color_I.png">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onPlayClick:" destination="-1" eventType="touchUpInside" id="B4y-PJ-4tO"/>
</connections>
</button>
<textView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." translatesAutoresizingMaskIntoConstraints="NO" id="cx9-0K-P9L" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="0.0" y="322" width="365" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="372" y="347" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ephemeral_messages_color_A.png" id="7JB-ZL-0lZ" userLabel="ephemeralIcon">
<rect key="frame" x="351" y="346" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IRV-qN-sRj" userLabel="ephemeralTime">
<rect key="frame" x="282" y="346" width="65" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view tag="28021" contentMode="scaleToFill" id="bhq-9n-zYF" userLabel="voiceRecording">
<rect key="frame" x="7" y="262" width="351" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<subviews>
<view tag="28024" contentMode="scaleToFill" id="a7V-w2-tIE" userLabel="vr_wave_mask_playback">
<rect key="frame" x="8" y="10" width="335" height="42"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.93333333330000001" green="0.93333333330000001" blue="0.93333333330000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<button opaque="NO" tag="28028" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7Zn-bp-e0Y">
<rect key="frame" x="8" y="13" width="35" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="vr_play.png"/>
<connections>
<action selector="onVRPlayPauseClick:" destination="-1" eventType="touchUpInside" id="ffk-KD-q9Q"/>
</connections>
</button>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="28025" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="vr_wave.png" translatesAutoresizingMaskIntoConstraints="NO" id="B5G-6m-k8r">
<rect key="frame" x="52" y="16" width="223" height="27"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." translatesAutoresizingMaskIntoConstraints="NO" id="cx9-0K-P9L" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="0.0" y="312" width="365" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="372" y="337" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="28027" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VUD-m6-g1J">
<rect key="frame" x="287" y="20" width="48" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ephemeral_messages_color_A.png" id="7JB-ZL-0lZ" userLabel="ephemeralIcon">
<rect key="frame" x="351" y="336" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IRV-qN-sRj" userLabel="ephemeralTime">
<rect key="frame" x="282" y="336" width="65" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view tag="28021" contentMode="scaleToFill" id="bhq-9n-zYF" userLabel="voiceRecording">
<rect key="frame" x="7" y="252" width="351" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<subviews>
<view tag="28024" contentMode="scaleToFill" id="a7V-w2-tIE" userLabel="vr_wave_mask_playback">
<rect key="frame" x="8" y="10" width="335" height="42"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.93333333330000001" green="0.93333333330000001" blue="0.93333333330000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<button opaque="NO" tag="28028" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7Zn-bp-e0Y">
<rect key="frame" x="8" y="13" width="35" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="vr_play.png"/>
<connections>
<action selector="onVRPlayPauseClick:" destination="-1" eventType="touchUpInside" id="ffk-KD-q9Q"/>
</connections>
</button>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="28025" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="vr_wave.png" translatesAutoresizingMaskIntoConstraints="NO" id="B5G-6m-k8r">
<rect key="frame" x="52" y="16" width="223" height="27"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="28027" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VUD-m6-g1J">
<rect key="frame" x="287" y="20" width="48" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="5ZI-Ip-lGl" appends="YES" id="1iY-46-rRR"/>
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="FIv-pl-I8J"/>
<outletCollection property="gestureRecognizers" destination="daf-cW-dRj" appends="YES" id="qgk-YT-Grl"/>
</connections>
</view>
</subviews>
@ -229,21 +246,11 @@
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-118.40000000000001" y="244.22788605697153"/>
</view>
<tapGestureRecognizer id="5ZI-Ip-lGl" userLabel="resendClick">
<connections>
<action selector="onResendClick:" destination="-1" id="XOF-AF-Hes"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer id="aDF-hC-ddO" userLabel="imageClick">
<connections>
<action selector="onImageClick:" destination="-1" id="feN-LT-89b"/>
</connections>
</tapGestureRecognizer>
<pongPressGestureRecognizer allowableMovement="10" minimumPressDuration="0.5" id="daf-cW-dRj" userLabel="plusClick">
<connections>
<action selector="onPlusClick:" destination="-1" id="oFW-FN-6xV"/>
</connections>
</pongPressGestureRecognizer>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
@ -254,6 +261,7 @@
<image name="color_M.png" width="2" height="2"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="linphone_logo.png" width="41.599998474121094" height="42.400001525878906"/>
<image name="menu_reply_default.png" width="25" height="25"/>
<image name="vr_play.png" width="200" height="200"/>
<image name="vr_wave.png" width="1078" height="90"/>
</resources>

View file

@ -18,6 +18,8 @@
<outlet property="imdmIcon" destination="Nod-GX-0kg" id="Pa7-l6-pGh"/>
<outlet property="innerView" destination="vdk-RV-QRU" id="wQs-CR-Pm3"/>
<outlet property="messageText" destination="CYa-If-oB4" id="7xm-UF-1qB"/>
<outlet property="replyTransferIcon" destination="asp-BT-0GQ" id="20N-AN-DV1"/>
<outlet property="replyTransferLabel" destination="169-mW-EH1" id="KVp-dz-HS5"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
@ -41,6 +43,17 @@
<rect key="frame" x="39" y="20" width="143" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="menu_reply_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="asp-BT-0GQ" userLabel="replyTransferIcon">
<rect key="frame" x="4" y="3" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Répondu" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="169-mW-EH1" userLabel="replyTransferLabel">
<rect key="frame" x="17" y="3" width="69" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="ZIO-Cb-28G" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="126" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
@ -80,5 +93,6 @@
<image name="chat_read.png" width="20" height="20"/>
<image name="color_A.png" width="2" height="2"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="menu_reply_default.png" width="25" height="25"/>
</resources>
</document>

View file

@ -14,6 +14,7 @@
<outlet property="chatContentLabel" destination="21" id="24"/>
<outlet property="chatLatestTimeLabel" destination="r7A-Mk-LQX" id="J0r-yr-YLk"/>
<outlet property="ephemeral" destination="q18-yi-ol3" id="xhD-9e-BbP"/>
<outlet property="forwardIcon" destination="rbY-QS-6QH" id="09w-ky-Ezs"/>
<outlet property="imdmIcon" destination="aa2-Kl-c1H" id="rnr-XY-r9K"/>
<outlet property="securityImage" destination="kdl-Ln-eWv" id="S9v-cN-u4w"/>
<outlet property="unreadCountLabel" destination="ZXq-Do-7Ua" id="anx-Na-sYz"/>
@ -64,10 +65,6 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="ephemeral_messages_color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="q18-yi-ol3">
<rect key="frame" x="338" y="51" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7DE-KJ-9Q3" userLabel="unreadCountView" customClass="UIBouncingView">
<rect key="frame" x="338" y="12" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
@ -90,6 +87,14 @@
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="forward_message_default.png" id="rbY-QS-6QH" userLabel="transferIcon">
<rect key="frame" x="338" y="33" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="ephemeral_messages_color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="q18-yi-ol3">
<rect key="frame" x="338" y="54" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
@ -101,6 +106,7 @@
<image name="chat_list_indicator.png" width="28" height="28"/>
<image name="chat_read.png" width="20" height="20"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="forward_message_default.png" width="187" height="148"/>
<image name="security_1_indicator.png" width="27.5" height="32.5"/>
</resources>
</document>

View file

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" 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="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatReplyBubbleView" customModule="linphoneapp" customModuleProvider="target">
<connections>
<outlet property="contentCollection" destination="ZgY-Ye-8DD" id="hlD-Fw-g1z"/>
<outlet property="dismissButton" destination="KrT-j6-YOy" id="K5m-Mw-Cjx"/>
<outlet property="leftBar" destination="Iov-AL-8Xz" id="eKb-4B-unZ"/>
<outlet property="originalMessageGone" destination="B26-sw-o4w" id="Gwh-dh-GRN"/>
<outlet property="senderName" destination="uuW-tW-1Sj" id="Yao-6A-SBh"/>
<outlet property="textContent" destination="Czc-VH-qiH" id="e35-qw-Sz3"/>
<outlet property="view" destination="i5M-Pr-FkT" id="kJN-7M-ijh"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="350" height="120"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" tag="290394" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uuW-tW-1Sj" userLabel="nameWithTextContent">
<rect key="frame" x="16" y="2" width="312" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="290395" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" minimumFontSize="14" translatesAutoresizingMaskIntoConstraints="NO" id="Czc-VH-qiH" userLabel="textContent">
<rect key="frame" x="16" y="83" width="312" height="32"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="ZgY-Ye-8DD">
<rect key="frame" x="16" y="23" width="312" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="gR0-ml-XVX">
<size key="itemSize" width="55" height="55"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
<view tag="290393" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Iov-AL-8Xz" userLabel="leftBar">
<rect key="frame" x="0.0" y="0.0" width="10" height="120"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Original message does not exist anymore" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B26-sw-o4w" userLabel="originalMessageGone">
<rect key="frame" x="16" y="6" width="312" height="109"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="italicSystem" pointSize="15"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="290399" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KrT-j6-YOy" userLabel="dismiss">
<rect key="frame" x="327" y="51" width="20" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<state key="normal" image="reply_cancel.png"/>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="85.507246376811594" y="111.83035714285714"/>
</view>
</objects>
<resources>
<image name="reply_cancel.png" width="60" height="60"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -15,6 +13,7 @@
<outlet property="authView" destination="CCn-Oz-I0M" id="fSM-6k-paN"/>
<outlet property="cancelButton" destination="B1K-CB-3of" id="KKi-Xc-ldA"/>
<outlet property="confirmationButton" destination="SbQ-re-fGQ" id="yiv-a9-o8E"/>
<outlet property="forwardImage" destination="1Wh-Yi-cUe" id="YQq-bt-pk1"/>
<outlet property="securityImage" destination="bbo-g3-bGy" id="qZa-li-yrl"/>
<outlet property="titleLabel" destination="jLz-g1-cTe" id="qaj-OB-2r1"/>
<outlet property="view" destination="2Vb-Xy-rci" id="nNw-EJ-AY3"/>
@ -25,26 +24,26 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.89999999999999991" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="cqN-1f-6SE" userLabel="backgroundColor">
<imageView userInteractionEnabled="NO" alpha="0.89999999999999991" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_C.png" translatesAutoresizingMaskIntoConstraints="NO" id="cqN-1f-6SE" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="377" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<view contentMode="scaleToFill" id="2BQ-o9-xv2">
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2BQ-o9-xv2">
<rect key="frame" x="28" y="139" width="320" height="365"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" insetsLayoutMarginsFromSafeArea="NO" image="security_2_indicator.png" id="bbo-g3-bGy" userLabel="securityImage">
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" image="security_2_indicator.png" translatesAutoresizingMaskIntoConstraints="NO" id="bbo-g3-bGy" userLabel="securityImage">
<rect key="frame" x="130" y="0.0" width="56" height="68"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Are you sure you want to delete all your selection?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="jLz-g1-cTe" userLabel="titleLabel">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Are you sure you want to delete all your selection?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="jLz-g1-cTe" userLabel="titleLabel">
<rect key="frame" x="-10" y="15" width="336" height="279"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="B1K-CB-3of" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="B1K-CB-3of" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="8" y="308" width="139" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="CANCEL" backgroundImage="color_H.png">
@ -56,11 +55,11 @@
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="LvF-N2-56g"/>
</connections>
</button>
<view hidden="YES" contentMode="scaleToFill" id="CCn-Oz-I0M" userLabel="authView">
<view hidden="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CCn-Oz-I0M" userLabel="authView">
<rect key="frame" x="61" y="273" width="240" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="lWW-wB-FMR" userLabel="authButton">
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lWW-wB-FMR" userLabel="authButton">
<rect key="frame" x="26" y="2" width="17" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="checkbox_unchecked.png"/>
@ -69,7 +68,7 @@
<action selector="onAuthClick:" destination="-1" eventType="touchUpInside" id="9A4-ZX-cXA"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Do not show again" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dQL-Sf-slc">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Do not show again" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dQL-Sf-slc">
<rect key="frame" x="55" y="2" width="176" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -78,7 +77,7 @@
</label>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="SbQ-re-fGQ" userLabel="confirmationButton" customClass="UIRoundBorderedButton">
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SbQ-re-fGQ" userLabel="confirmationButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="169" y="308" width="143" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="DELETE" backgroundImage="color_I.png">
@ -90,22 +89,27 @@
<action selector="onConfirmationClick:" destination="-1" eventType="touchUpInside" id="0np-r7-R0W"/>
</connections>
</button>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="forward_message_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="1Wh-Yi-cUe">
<rect key="frame" x="89" y="50" width="138" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<point key="canvasLocation" x="872" y="261.76911544227886"/>
<point key="canvasLocation" x="871.20000000000005" y="261.31934032983509"/>
</view>
</objects>
<resources>
<image name="checkbox_checked.png" width="17" height="17"/>
<image name="checkbox_unchecked.png" width="17" height="17"/>
<image name="checkbox_checked.png" width="27.200000762939453" height="27.200000762939453"/>
<image name="checkbox_unchecked.png" width="27.200000762939453" height="27.200000762939453"/>
<image name="color_C.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="color_H.png" width="2" height="2"/>
<image name="color_I.png" width="2" height="2"/>
<image name="color_M.png" width="2" height="2"/>
<image name="security_2_indicator.png" width="27" height="32"/>
<image name="forward_message_default.png" width="187" height="148"/>
<image name="security_2_indicator.png" width="27.5" height="32.5"/>
</resources>
</document>

View file

@ -41,7 +41,6 @@
@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *imageGestureRecognizer;
@property (weak, nonatomic) IBOutlet UIButton *fileButton;
@property (weak, nonatomic) IBOutlet UIView *fileView;
@property (strong, nonatomic) IBOutlet UILongPressGestureRecognizer *plusLongGestureRecognizer;
@property(strong, nonatomic) NSMutableArray<UIChatContentView *> *contentViews;
// Video recordings
@ -61,10 +60,8 @@
- (IBAction)onDownloadClick:(id)event;
- (IBAction)onImageClick:(id)event;
- (IBAction)onCancelClick:(id)sender;
- (IBAction)onResendClick:(id)event;
- (IBAction)onPlayClick:(id)sender;
- (IBAction)onFileClick:(id)sender;
- (IBAction)onPlusClick:(id)sender;
@end

View file

@ -61,8 +61,13 @@
assetIsLoaded = FALSE;
self.contentView.userInteractionEnabled = NO;
_contentViews = [[NSMutableArray alloc] init];
self.vrWaveMaskPlayback.layer.cornerRadius = 10.0f;
self.vrWaveMaskPlayback.layer.masksToBounds = YES;
self.vrView.layer.cornerRadius = 30.0f;
self.vrView.layer.masksToBounds = YES;
[self.innerView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onPopupMenuPressed)]];
self.messageText.userInteractionEnabled = false;
}
return self;
}
@ -82,7 +87,6 @@
- (void)setChatMessage:(LinphoneChatMessage *)amessage {
_imageGestureRecognizer.enabled = NO;
_plusLongGestureRecognizer.enabled = NO;
_messageImageView.image = nil;
_finalImage.image = nil;
_finalImage.hidden = TRUE;
@ -115,7 +119,6 @@
_messageImageView.hidden = YES;
_finalImage.hidden = NO;
_fileView.hidden = YES;
_plusLongGestureRecognizer.enabled = YES;
[self layoutSubviews];
});
}
@ -151,7 +154,6 @@
[_messageImageView stopLoading];
_messageImageView.hidden = YES;
_imageGestureRecognizer.enabled = YES;
_plusLongGestureRecognizer.enabled = YES;
_finalImage.hidden = NO;
[self layoutSubviews];
});
@ -499,25 +501,6 @@
}];
}
- (IBAction)onPlusClick:(id)sender {
UILongPressGestureRecognizer *gesture = (UILongPressGestureRecognizer *)sender;
if (gesture.state != UIGestureRecognizerStateBegan) {
// allow only one click once time
return;
}
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:@""];
dispatch_async(dispatch_get_main_queue(), ^{
[sheet addButtonWithTitle:NSLocalizedString(@"Save to Gallery", nil)
block:^() {
LinphoneContent *content = linphone_chat_message_get_file_transfer_information(self.message);
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
[ChatConversationView writeMediaToGallery:name fileType:[NSString stringWithUTF8String:linphone_content_get_type(content)?:""]];
}];
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
[sheet showInView:PhoneMainView.instance.view];
});
}
- (IBAction)onFileClick:(id)sender {
ChatConversationView *view = VIEW(ChatConversationView);
@ -545,16 +528,6 @@
}
}
- (void)onResendClick:(id)event {
if (_downloadButton.hidden == NO) {
// if download button is displayed, click on it
[self onDownloadClick:event];
} else if (_cancelButton.hidden == NO) {
[self onCancelClick:event];
} else {
[super onResend];
}
}
- (IBAction)onImageClick:(id)event {
if (_finalImage.tag == FILE_ICON_TAG) {
@ -563,7 +536,7 @@
}
LinphoneChatMessageState state = linphone_chat_message_get_state(self.message);
if (state == LinphoneChatMessageStateNotDelivered) {
[self onResendClick:event];
return;
} else {
if (![_messageImageView isLoading]) {
ImageView *view = VIEW(ImageView);
@ -768,6 +741,14 @@
} else {
_vrView.hidden = YES;
}
CGRect r = super.photoCellContentView.frame;
r.origin.y = linphone_chat_message_is_reply(super.message) ? super.replyView.view.frame.origin.y + super.replyView.view.frame.size.height + 10 : 7 ;
super.photoCellContentView.frame = r;
r = super.photoCellContentView.frame;
r.origin.y = linphone_chat_message_is_forward(super.message) ? super.contactDateLabel.frame.origin.y + super.contactDateLabel.frame.size.height + 3 : r.origin.y;
super.photoCellContentView.frame = r;
self.messageText.frame = textFrame;
}
@ -841,6 +822,14 @@ static AVAudioPlayer* utilityPlayer;
}
}
// menu
-(void) onPopupMenuPressed {
[super onPopupMenuPressed];
}
@end

View file

@ -22,6 +22,7 @@
#import "UITextViewNoDefine.h"
#import "ChatConversationTableView.h"
#import "UIRoundedImageView.h"
#import "UIChatReplyBubbleView.h"
#define CELL_IMAGE_X_MARGIN 100
#define IMAGE_DEFAULT_WIDTH 120
@ -30,7 +31,7 @@
#define VOICE_RECORDING_PLAYER_WIDTH 300
@interface UIChatBubbleTextCell : UITableViewCell <UIDocumentPickerDelegate>
@interface UIChatBubbleTextCell : UITableViewCell <UIDocumentPickerDelegate, UITableViewDataSource,UITableViewDelegate>
@property(readonly, nonatomic) LinphoneEventLog *event;
@property(readonly, nonatomic) LinphoneChatMessage *message;
@ -50,6 +51,22 @@
@property (weak, nonatomic) IBOutlet UIView *innerView;
@property (weak, nonatomic) IBOutlet UILabel *ephemeralTime;
@property (weak, nonatomic) IBOutlet UIImageView *ephemeralIcon;
@property ChatConversationTableView *tableController;
@property BOOL popupMenuAllowed;
// Message popup menu
@property UITableView *popupMenu;
@property NSMutableArray *messageActionsTitles;
@property NSMutableArray *messageActionsIcons;
@property NSMutableArray *messageActionsBlocks;
// Message reply/transfer
@property UIChatReplyBubbleView *replyView;
@property UILabel *replyOrForward;
@property (weak, nonatomic) IBOutlet UIImageView *replyTransferIcon;
@property (weak, nonatomic) IBOutlet UILabel *replyTransferLabel;
@property (weak, nonatomic) IBOutlet UIView *photoCellContentView;
@property(nonatomic) BOOL isFirst;
@property(nonatomic) BOOL isLast;
@ -67,8 +84,6 @@
- (void)clearEncryptedFiles;
- (void)onDelete;
- (void)onResend;
- (void)onLime;
- (void)update;
- (void)displayImdmStatus:(LinphoneChatMessageState)state;
@ -77,5 +92,6 @@
+ (CGSize)computeBoundingBox:(NSString *)text size:(CGSize)size font:(UIFont *)font;
+ (NSString *)ContactDateForChat:(LinphoneChatMessage *)message;
+(LinphoneContent *) voiceContent:(LinphoneChatMessage *)message;
-(void) onPopupMenuPressed;
-(void) dismissPopup;
@end

View file

@ -20,6 +20,7 @@
#import "UIChatBubbleTextCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "Utils.h"
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
@ -28,6 +29,8 @@
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString *)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
if ([identifier isEqualToString:NSStringFromClass(self.class)]) {
@ -40,22 +43,11 @@
[self addSubview:sub];
}
}
[_innerView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onPopupMenuPressed)]];
_messageText.userInteractionEnabled = false;
UITapGestureRecognizer *limeRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLime)];
limeRecognizer.numberOfTapsRequired = 1;
//[_LIMEKO addGestureRecognizer:limeRecognizer];
//_LIMEKO.userInteractionEnabled = YES;
UITapGestureRecognizer *resendRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer.numberOfTapsRequired = 1;
[_bubbleView addGestureRecognizer:resendRecognizer];
_imdmIcon.userInteractionEnabled = YES;
UITapGestureRecognizer *resendRecognizer2 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer2.numberOfTapsRequired = 1;
//[_imdmLabel addGestureRecognizer:resendRecognizer2];
//_imdmLabel.userInteractionEnabled = YES;
self.contentView.userInteractionEnabled = NO;
return self;
@ -205,11 +197,12 @@
_avatarImage.hidden = !_isFirst;
}
// Not use [UIImage imageNamed], it takes too much time
NSString *imageName = outgoing ? @"color_A.png" : @"color_D.png";
_backgroundColorImage.image =
[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] bundlePath],imageName]];
_backgroundColorImage.image = nil;
_backgroundColorImage.backgroundColor = outgoing ? [UIColor color:@"A"] : [UIColor color:@"D"];
// set maskedCorners
if (@available(iOS 11.0, *)) {
_backgroundColorImage.layer.cornerRadius = 10;
@ -255,6 +248,7 @@
frame.origin.y = _isFirst ? 20 : 0;
_innerView.frame = frame;
[_messageText setAccessibilityLabel:outgoing ? @"Outgoing message" : @"Incoming message"];
if (outgoing &&
(state == LinphoneChatMessageStateDeliveredToUser || state == LinphoneChatMessageStateDisplayed ||
@ -262,6 +256,23 @@
[self displayImdmStatus:state];
} else
[self displayImdmStatus:LinphoneChatMessageStateInProgress];
if (linphone_chat_message_is_reply(_message)) {
if (_replyView == nil) {
_replyView = [[UIChatReplyBubbleView alloc] initWithNibName:@"UIChatReplyBubbleView" bundle:nil];
[self.innerView addSubview:_replyView.view];
}
_replyView.view.hidden = false;
CGRect replyFrame = CGRectMake(_contactDateLabel.frame.origin.x, _contactDateLabel.frame.origin.y+_contactDateLabel.frame.size.height,self.contactDateLabel.frame.size.width, REPLY_CHAT_BUBBLE_HEIGHT);
_replyView.view.frame = replyFrame;
[_replyView configureForMessage:linphone_chat_message_get_reply_message(_message) withDimissBlock:^{} hideDismiss:true withClickBlock:^{
[_tableController scrollToMessage:linphone_chat_message_get_reply_message(_message)];
}];
} else {
if (_replyView)
_replyView.view.hidden = true;
}
}
- (void)setEditing:(BOOL)editing {
@ -269,7 +280,6 @@
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
_messageText.userInteractionEnabled = !editing;
_resendRecognizer.enabled = !editing;
}
@ -300,94 +310,6 @@
}
}
- (void)onLime {
/*if (!_LIMEKO.hidden)
[self displayLIMEWarning];*/
}
- (void)onResend {
if (!linphone_core_is_network_reachable(LC)) {
[PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView:@"send a message"] animated:YES completion:nil];
//return;
}
if (_message == nil || !linphone_chat_message_is_outgoing(_message))
return;
LinphoneChatMessageState state = linphone_chat_message_get_state(_message);
if (state != LinphoneChatMessageStateNotDelivered && state != LinphoneChatMessageStateFileTransferError)
return;
const bctbx_list_t *contents = linphone_chat_message_get_contents(_message);
LinphoneContent *voiceContent = [UIChatBubbleTextCell voiceContent:_message];
size_t contentCount = bctbx_list_size(contents);
if (voiceContent)
contentCount--;
BOOL multiParts = ((linphone_chat_message_get_text_content(_message) != NULL) ? contentCount > 2 : contentCount > 1);
if (multiParts) {
FileContext *newfileContext = [[FileContext alloc] init];
[newfileContext clear];
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:_message];
int i;
const bctbx_list_t *it;
for (it = contents, i=0; it != NULL; it=bctbx_list_next(it)){
LinphoneContent *content = (LinphoneContent *)it->data;
if (linphone_content_is_voice_recording(content)) {
continue;
}
if (linphone_content_is_file_transfer(content) || linphone_content_is_file(content)){
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath = [encrptedFilePaths valueForKey:name];
if (filePath == NULL) {
filePath = [LinphoneManager validFilePath:name];
}
[newfileContext addObject:[NSData dataWithContentsOfFile:filePath] name:name type:[NSString stringWithUTF8String:linphone_content_get_type(content)]];
}
}
[self onDelete];
dispatch_async(dispatch_get_main_queue(), ^ {
const char *text = linphone_chat_message_get_text_content(_message);
[_chatRoomDelegate resendMultiFiles:newfileContext message: text? [NSString stringWithUTF8String:text]: NULL voiceContent:voiceContent];
});
return;
}
if (!voiceContent && contentCount == 1 && linphone_chat_message_get_file_transfer_information(_message) != NULL) {
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message];
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message];
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:_message];
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:self.message];
[self onDelete];
dispatch_async(dispatch_get_main_queue(), ^ {
NSData *data = NULL;
if (filePath) {
data = [NSData dataWithContentsOfFile:filePath];
}
const char *text = linphone_chat_message_get_text_content(_message);
NSString *str = text ? [NSString stringWithUTF8String:text] : NULL;
if (localImage) {
[_chatRoomDelegate resendFile: (data?:[ChatConversationView getFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str voiceContent:voiceContent];
} else if (localVideo) {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str voiceContent:voiceContent];
} else {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str voiceContent:voiceContent];
}
});
} else {
[self onDelete];
double delayInSeconds = 0.4;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
NSString *text = self.textMessage;
if (voiceContent && [text isEqualToString:@"🗻"])
text = nil;
[_chatRoomDelegate resendChat:text withExternalUrl:nil voiceContent:voiceContent];
});
}
}
#pragma mark - State changed handling
static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState state) {
LOGI(@"State for message [%p] changed to %s", msg, linphone_chat_message_state_to_string(state));
@ -442,9 +364,15 @@ static const CGFloat CELL_MIN_HEIGHT = 65.0f;
static const CGFloat CELL_MIN_WIDTH = 190.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 68 + 10.0f;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
static const CGFloat REPLY_CHAT_BUBBLE_HEIGHT = 120;
static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width {
return [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
CGSize size = [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
size.height += linphone_chat_message_is_forward(chat) || linphone_chat_message_is_reply(chat) ? REPLY_OR_FORWARD_TAG_HEIGHT : 0;
size.height += linphone_chat_message_is_reply(chat) ? REPLY_CHAT_BUBBLE_HEIGHT+5 : 0;
return size;
}
+ (CGSize)ViewHeightForFile:(int)width {
@ -456,20 +384,38 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
}
+(NSString *)formattedDuration:(long)valueMs {
return [NSString stringWithFormat:@"%02ld:%02ld", valueMs/ 60, (valueMs % 60) ];
}
+(NSString *) recordingDuration:(NSString *) _voiceRecordingFile{
NSError *error = nil;
AVAudioPlayer* utilityPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:_voiceRecordingFile] error:&error]; // Workaround as opening multiple linphone_players at the same time can cause crash (here for example layout refreshed whilst a voice memo is playing
return [self formattedDuration:utilityPlayer.duration];
utilityPlayer = nil;
}
+ (UIImage *)getImageFromFileName:(NSString *)fileName {
NSString *extension = [[fileName.lowercaseString componentsSeparatedByString:@"."] lastObject];
UIImage *image;
if ([extension isEqualToString:@"pdf"])
image = [UIImage imageNamed:@"file_pdf_default"];
else if ([@[@"png", @"jpg", @"jpeg", @"bmp", @"heic"] containsObject:extension])
image = [UIImage imageNamed:@"file_picture_default"];
else if ([@[@"mkv", @"avi", @"mov", @"mp4"] containsObject:extension])
image = [UIImage imageNamed:@"file_video_default"];
else if ([@[@"wav", @"au", @"m4a"] containsObject:extension])
image = [UIImage imageNamed:@"file_audio_default"];
else
image = [UIImage imageNamed:@"file_default"];
return [SwiftUtil textToImageWithDrawText:fileName inImage:image];
NSString * text = fileName;
if ([fileName containsString:@"voice-recording"]) {
image = [UIImage imageNamed:@"file_voice_default"];
text = [self recordingDuration:[LinphoneManager validFilePath:fileName]];
} else {
if ([extension isEqualToString:@"pdf"])
image = [UIImage imageNamed:@"file_pdf_default"];
else if ([@[@"png", @"jpg", @"jpeg", @"bmp", @"heic"] containsObject:extension])
image = [UIImage imageNamed:@"file_picture_default"];
else if ([@[@"mkv", @"avi", @"mov", @"mp4"] containsObject:extension])
image = [UIImage imageNamed:@"file_video_default"];
else if ([@[@"wav", @"au", @"m4a"] containsObject:extension])
image = [UIImage imageNamed:@"file_audio_default"];
else
image = [UIImage imageNamed:@"file_default"];
}
return [SwiftUtil textToImageWithDrawText:text inImage:image];
}
+ (UIImage *)getImageFromContent:(LinphoneContent *)content filePath:(NSString *)filePath; {
@ -630,7 +576,8 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
size = [self computeBoundingBox:messageText
size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX)
font:messageFont];
} else {
size.width += 4;
} else { // Just file or file with text
LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(chat);
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat];
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:chat];
@ -671,10 +618,11 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
} else if (voiceContent){
return [self addVoicePlayerToSize:[self ViewHeightForFile:width] withMargins:true];
} else {
image = [UIChatBubbleTextCell getImageFromFileName:fileName];
image = nil;
originalImageSize = CGSizeMake(140, 140);
}
originalImageSize = image.size;
if (image != nil)
originalImageSize = image.size;
} else {
if (!localImage && !localVideo) {
//We are loading the image
@ -781,15 +729,45 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
int origin_x;
bubbleFrame.size = [self.class ViewSizeForMessage:_message withWidth:available_width];
if (linphone_chat_message_is_reply(_message)) {
bubbleFrame.size.width = MAX(bubbleFrame.size.width, 300);
}
if (tableView.isEditing) {
origin_x = 0;
} else {
origin_x = (is_outgoing ? self.frame.size.width - bubbleFrame.size.width : 0);
}
CGRect r = _messageText.frame;
r.origin.y = linphone_chat_message_is_reply(_message) ? _replyView.view.frame.origin.y + _replyView.view.frame.size.height + 5 : 3;
_messageText.frame = r;
r = _messageText.frame;
r.origin.y = linphone_chat_message_is_forward(_message) ? _contactDateLabel.frame.origin.y + _contactDateLabel.frame.size.height + 5 : r.origin.y;
_messageText.frame = r;
_replyTransferIcon.hidden = ! linphone_chat_message_is_reply(_message) && !linphone_chat_message_is_forward(_message);
_replyTransferLabel.hidden = ! linphone_chat_message_is_reply(_message) && !linphone_chat_message_is_forward(_message);
if (linphone_chat_message_is_reply(_message)) {
CGRect replyFrame = CGRectMake(10, _replyTransferLabel.frame.origin.y+_replyTransferLabel.frame.size.height+5,MAX(self.contactDateLabel.frame.size.width-20,180), REPLY_CHAT_BUBBLE_HEIGHT);
_replyView.view.frame = replyFrame;
_replyTransferIcon.image = [UIImage imageNamed:@"menu_reply_default"];
_replyTransferLabel.text = NSLocalizedString(@"Answer",nil);
_replyTransferLabel.textColor = [UIColor lightGrayColor];
}
if (linphone_chat_message_is_forward(_message)) {
_replyTransferIcon.image = [UIImage imageNamed:@"menu_forward_default"];
_replyTransferLabel.text = NSLocalizedString(@"Transferred",nil);
_replyTransferLabel.textColor = [UIColor darkGrayColor];
}
bubbleFrame.origin.x = origin_x;
_bubbleView.frame = bubbleFrame;
}
}
@ -817,4 +795,173 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
return mediaSize;
}
// Message popup menu
// Copy text -> if has text
// Transfer -> always
// Reply -> always
// IMDM Status -> out
// Delete -> always
-(void) buildActions {
LinphoneChatMessage *message = self.message;
_messageActionsTitles = [[NSMutableArray alloc] init];
_messageActionsBlocks = [[NSMutableArray alloc] init];
_messageActionsIcons = [[NSMutableArray alloc] init];
UIChatBubbleTextCell *thiz = self;
LinphoneChatMessageState state = linphone_chat_message_get_state(self.message);
if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) {
[_messageActionsTitles addObject:NSLocalizedString(@"Resend", nil)];
[_messageActionsIcons addObject:@"menu_resend_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
if (!linphone_core_is_network_reachable(LC)) {
[PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView:@"send a message"] animated:YES completion:nil];
return;
}
linphone_chat_message_send(message);
}];
}
if (linphone_chat_message_get_utf8_text(message)) {
[_messageActionsTitles addObject:NSLocalizedString(@"Copy text", nil)];
[_messageActionsIcons addObject:@"menu_copy_text_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
[UIPasteboard.generalPasteboard setString:[NSString stringWithUTF8String:linphone_chat_message_get_text_content(message)]];
}];
}
[_messageActionsTitles addObject:NSLocalizedString(@"Forward", nil)];
[_messageActionsIcons addObject:@"menu_forward_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
VIEW(ChatConversationView).pendingForwardMessage = message;
[PhoneMainView.instance changeCurrentView:VIEW(ChatsListView).compositeViewDescription];
}];
[_messageActionsTitles addObject:NSLocalizedString(@"Reply", nil)];
[_messageActionsIcons addObject:@"menu_reply_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
[VIEW(ChatConversationView) initiateReplyViewForMessage:message];
}];
if (linphone_chat_message_is_outgoing(self.message) && linphone_chat_room_get_nb_participants(linphone_chat_message_get_chat_room(self.message)) > 1) {
[_messageActionsTitles addObject:NSLocalizedString(@"Infos", nil)];
[_messageActionsIcons addObject:@"menu_info"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
ChatConversationImdnView *view = VIEW(ChatConversationImdnView);
view.msg = message;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}];
}
[_messageActionsTitles addObject:NSLocalizedString(@"Delete", nil)];
[_messageActionsIcons addObject:@"menu_delete"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
linphone_chat_room_delete_message(linphone_chat_message_get_chat_room(message), message);
[VIEW(ChatConversationView).tableController reloadData];
}];
}
-(void) onPopupMenuPressed {
if (_popupMenu != nil)
[self dismissPopup];
if (!self.popupMenuAllowed)
return;
[VIEW(ChatConversationView).tableController dismissMessagesPopups];
self.innerView.layer.borderWidth = 3;
self.innerView.layer.borderColor = [UIColor color:@"A"].CGColor;
[self buildActions];
int width = 250;
int cellHeight = 44;
int numberOfItems = (int) _messageActionsTitles.count;
CGRect screenRect = UIScreen.mainScreen.bounds;
int menuHeight = numberOfItems * cellHeight;
CGRect frame = CGRectMake(
linphone_chat_message_is_outgoing(self.message) ? screenRect.size.width - width - 10 : 10,
(self.frame.origin.y + self.frame.size.height) - [VIEW(ChatConversationView).tableController .tableView contentOffset].y > screenRect.size.height /2 ? self.frame.origin.y - menuHeight - 10: self.frame.origin.y + self.frame.size.height,
width,
menuHeight);
_popupMenu = [[UITableView alloc]initWithFrame:frame];
_popupMenu.dataSource = self;
_popupMenu.delegate = self;
_popupMenu.layer.shadowColor = [UIColor lightGrayColor].CGColor;
_popupMenu.layer.shadowOpacity = 0.5;
_popupMenu.layer.shadowOffset = CGSizeZero;
_popupMenu.layer.shadowRadius = 5;
_popupMenu.layer.masksToBounds = false;
_popupMenu.tableFooterView = [UIView new];
_popupMenu.editing = NO;
_popupMenu.userInteractionEnabled = true;
[_popupMenu reloadData];
[VIEW(ChatConversationView).tableController.view addSubview:_popupMenu];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOutsideMenu:)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.numberOfTapsRequired = 1;
[VIEW(ChatConversationView).tableController.view addGestureRecognizer:tapGestureRecognizer];
}
-(void) dismissPopup {
if (!_popupMenu)
return;
[_popupMenu removeFromSuperview];
_popupMenu = nil;
self.innerView.layer.borderWidth = 0;
[self setNeedsLayout];
}
-(void) tapOutsideMenu:(UITapGestureRecognizer *) g {
CGPoint p = [g locationInView:VIEW(ChatConversationView).tableController.view];
if (!CGRectContainsPoint(_popupMenu.frame,p)) {
[self dismissPopup];
}
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
void (^ myblock)(void) = [_messageActionsBlocks objectAtIndex:indexPath.row];
[self dismissPopup];
myblock();
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_messageActionsTitles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.imageView.image = [[UIImage imageNamed:[_messageActionsIcons objectAtIndex:indexPath.row]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
cell.textLabel.text = [_messageActionsTitles objectAtIndex:indexPath.row];
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
if ([[_messageActionsIcons objectAtIndex:indexPath.row] isEqualToString:@"menu_delete"]) {
cell.textLabel.textColor = UIColor.redColor;
cell.imageView.tintColor = UIColor.redColor;
} else {
cell.imageView.tintColor = PhoneMainView.instance.darkMode ? UIColor.whiteColor : UIColor.blackColor;
}
return cell;
}
@end

View file

@ -38,6 +38,8 @@
@property(weak, nonatomic) IBOutlet UILabel *unreadCountLabel;
@property (weak, nonatomic) IBOutlet UIImageView *imdmIcon;
@property (weak, nonatomic) IBOutlet UIImageView *ephemeral;
@property (weak, nonatomic) IBOutlet UIImageView *forwardIcon;
- (id)initWithIdentifier:(NSString*)identifier;

View file

@ -46,6 +46,7 @@
- (void)setChatRoom:(LinphoneChatRoom *)achat {
chatRoom = achat;
[self update];
[self.forwardIcon setImageNamed:@"forward_message_default" tintColor:PhoneMainView.instance.darkMode ? UIColor.whiteColor : UIColor.darkGrayColor];
}
#pragma mark -

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIChatReplyBubbleView : UIViewController <UICollectionViewDataSource>
@property (weak, nonatomic) IBOutlet UILabel *senderName;
@property (weak, nonatomic) IBOutlet UIButton *dismissButton;
@property (weak, nonatomic) IBOutlet UIView *leftBar;
@property (weak, nonatomic) IBOutlet UIView *rightBar;
@property LinphoneChatMessage *message;
@property (weak, nonatomic) IBOutlet UILabel *textContent;
@property void (^ dismissAction)(void);
@property void (^ clickAction)(void);
@property (weak, nonatomic) IBOutlet UICollectionView *contentCollection;
@property NSArray *dataContent;
@property (weak, nonatomic) IBOutlet UILabel *originalMessageGone;
-(void) configureForMessage:(LinphoneChatMessage *)message withDimissBlock:(void (^)(void))dismissBlock hideDismiss:(BOOL)hideDismiss withClickBlock:(void (^)(void))clickBlock;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "UIChatReplyBubbleView.h"
#import "linphoneapp-Swift.h"
#import "Utils.h"
@interface UIChatReplyBubbleView ()
@end
@implementation UIChatReplyBubbleView
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
return self;
}
-(void) viewDidLoad {
_contentCollection.dataSource = self;
[_contentCollection registerClass:UICollectionViewCell.class forCellWithReuseIdentifier:@"dataContent"];
}
-(void) configureForMessage:(LinphoneChatMessage *)message withDimissBlock:(void (^)(void))dismissBlock hideDismiss:(BOOL)hideDismiss withClickBlock:(void (^)(void))clickBlock{
if (!message) {
_textContent.hidden = true;
_dismissButton.hidden = true;
_contentCollection.hidden = true;
_senderName.hidden = true;
_originalMessageGone.hidden = false;
return;
}
if (hideDismiss) {
self.view.layer.cornerRadius = 10;
self.view.layer.masksToBounds = true;
}
_originalMessageGone.hidden = true;
self.message = message;
self.dataContent = [self loadDataContent];
NSString *sender = [FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(message)];
_senderName.text = sender;
const char * text = linphone_chat_message_get_text_content(message);
if (text && strlen(text) == 0)
text = nil;
_textContent.text = text ? [NSString stringWithUTF8String:text] : @"";
_dismissButton.hidden = hideDismiss;
_dismissAction = dismissBlock;
_clickAction = clickBlock;
if (hideDismiss) {
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(onClick)];
[self.view addGestureRecognizer:singleFingerTap];
}
else
[_dismissButton addTarget:self action:@selector(dismissClick) forControlEvents:UIControlEventTouchUpInside];
self.view.backgroundColor = hideDismiss ? UIColor.whiteColor :(linphone_chat_message_is_outgoing(message) ? [[UIColor color:@"A"] colorWithAlphaComponent:0.2] : [[UIColor color:@"D"] colorWithAlphaComponent:0.2]);
_leftBar.backgroundColor = linphone_chat_message_is_outgoing(message) ? [UIColor color:@"A"] : [UIColor color:@"D"];
_leftBar.hidden = !hideDismiss;
_rightBar.backgroundColor = self.view.backgroundColor;
// Resize frame -> text or content only = 100, 145 otherwise
_contentCollection.hidden = self.dataContent.count == 0;
CGRect r = self.view.frame ;
r.size.width = self.view.superview.frame.size.width;
self.view.frame = r;
if (self.dataContent.count == 0) {
CGRect r = _textContent.frame;
r.origin.y = _contentCollection.frame.origin.y;
r.size.height = 87;
_textContent.frame = r;
}
if (text == nil) {
CGRect r = _contentCollection.frame;
r.origin.y = 30;
_contentCollection.frame = r;
}
}
-(NSArray *) loadDataContent {
NSMutableArray *result = [[NSMutableArray alloc] init];
const bctbx_list_t *contents = linphone_chat_message_get_contents(_message);
const char * text = linphone_chat_message_get_utf8_text(_message);
if (text && bctbx_list_size(contents) == 1)
return result;
for (const bctbx_list_t * it = contents; it != NULL; it=bctbx_list_next(it)){
LinphoneContent *content = (LinphoneContent *)it->data;
if (linphone_content_is_text(content))
continue;
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:_message];
NSString *filePath = encrptedFilePaths ? [encrptedFilePaths valueForKey:name] : nil;
if (filePath == NULL) {
filePath = [LinphoneManager validFilePath:name];
}
[result addObject:[UIChatBubbleTextCell getImageFromContent:content filePath:filePath]];
}
return result;
}
-(void) dismissClick {
_dismissAction();
}
-(void) onClick {
_clickAction();
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataContent.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"dataContent" forIndexPath:indexPath];
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
img.image = [self.dataContent objectAtIndex:indexPath.row];
[cell.contentView addSubview:img];
return cell;
}
@end

View file

@ -45,6 +45,7 @@ typedef void (^UIConfirmationBlock)(void);
@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *cancelButton;
@property (weak, nonatomic) IBOutlet UIImageView *securityImage;
@property (weak, nonatomic) IBOutlet UIImageView *forwardImage;
@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *confirmationButton;
@property (weak, nonatomic) IBOutlet UIView *authView;
@property(weak, nonatomic) IBOutlet UILabel *titleLabel;

View file

@ -0,0 +1,9 @@
/* Class = "UILabel"; text = "Original message removed"; ObjectID = "B26-sw-o4w"; */
"B26-sw-o4w.text" = "Original message does not exist anymore.";
/* Class = "UILabel"; text = "Label"; ObjectID = "Czc-VH-qiH"; */
"Czc-VH-qiH.text" = "Label";
/* Class = "UILabel"; text = "Label"; ObjectID = "uuW-tW-1Sj"; */
"uuW-tW-1Sj.text" = "Label";

View file

@ -0,0 +1,9 @@
/* Class = "UILabel"; text = "Original message removed"; ObjectID = "B26-sw-o4w"; */
"B26-sw-o4w.text" = "Le message original n'existe plus.";
/* Class = "UILabel"; text = "Label"; ObjectID = "Czc-VH-qiH"; */
"Czc-VH-qiH.text" = "Label";
/* Class = "UILabel"; text = "Label"; ObjectID = "uuW-tW-1Sj"; */
"uuW-tW-1Sj.text" = "Label";

View file

@ -121,6 +121,7 @@
- (BOOL)isIphoneXDevice;
+ (int)iphoneStatusBarHeight;
-(BOOL) darkMode;
@end

View file

@ -957,4 +957,15 @@ void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomSta
[controller dismissModalViewControllerAnimated:YES];
}
#pragma mark - Light/Dark mode
-(BOOL) darkMode {
if (@available(iOS 13.0, *)) {
UITraitCollection *collection = [UITraitCollection currentTraitCollection];
return collection.userInterfaceStyle == UIUserInterfaceStyleDark;
} else {
return false;
}
}
@end

View file

@ -1,46 +1,69 @@
//
// SwiftUtil.swift
// linphone
//
// Created by Tof on 23/07/2021.
//
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import UIKit
@objc class SwiftUtil: NSObject {
@objc static func textToImage(drawText text: String, inImage image: UIImage) -> UIImage {
let textColor = UIColor.black
let textFont = UIFont(name: "Helvetica", size: 12)!
let fontMax = UIFont.systemFont(ofSize: 30)
let backgroundColor = UIColor.white
let size = CGSize(width: 120, height: 120)
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()
backgroundColor.setFill()
context!.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
let textFontAttributes = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.paragraphStyle: paragraph,
] as [NSAttributedString.Key : Any]
image.draw(in: CGRect(origin: CGPoint(x: size.width/2 - (image.size.width)/2,y: 5), size: image.size))
let label = UILabel(frame: CGRect(x: 0,y: 0,width: size.width,height: 50))
label.numberOfLines = 0
label.font = fontMax
label.adjustsFontSizeToFitWidth = true
label.text = text
label.textColor = textColor
label.textAlignment = .center
label.allowsDefaultTighteningForTruncation = true
label.lineBreakMode = .byTruncatingTail
imageWithLabel(label: label).draw(in: CGRect(origin: CGPoint(x:0,y: 60), size: CGSize(width: size.width,height: 50)))
let view = UIView(frame: CGRect(x: 0,y: 0,width: size.width,height: 50))
view.addSubview(label)
label.sizeToFit()
image.draw(in: CGRect(origin: CGPoint(x: size.width/2 - (image.size.width)/2,y: 15), size: image.size))
let rect = CGRect(origin: CGPoint(x: 0,y: 70), size: CGSize(width: size.width, height: 30))
text.draw(in: rect, withAttributes: textFontAttributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
static func imageWithLabel(label: UILabel) -> UIImage {
UIGraphicsBeginImageContextWithOptions(label.frame.size, false, 0.0)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return img
}
}

View file

@ -24,11 +24,10 @@
@interface FileTransferDelegate : NSObject
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom andVoiceContent:(LinphoneContent *)voiceContent;
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key voiceContent:(LinphoneContent *)voiceContent;
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)uploadImage:(UIImage *)image forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality;
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name;
- (void)uploadVideo:(NSData *)data withassetId:(NSString *)phAssetId forChatRoom:(LinphoneChatRoom *)chatRoom;
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)cancel;
- (BOOL)download:(LinphoneChatMessage *)message;
- (void)stopAndDestroy;

View file

@ -102,7 +102,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
}
}
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key voiceContent:(LinphoneContent *)voiceContent{
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key rootMessage:(LinphoneChatMessage *)rootMessage{
if ([[LinphoneManager.instance fileTransferDelegates] containsObject:self]) {
LOGW(@"fileTransferDelegates has already added %p", self);
return;
@ -115,7 +115,8 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
linphone_content_set_subtype(content, [subtype UTF8String]);
linphone_content_set_name(content, [name UTF8String]);
linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name].UTF8String);
_message = linphone_chat_room_create_file_transfer_message(chatRoom, content);
_message = rootMessage;
linphone_chat_message_add_file_content(_message, content);
BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
if (!isOneToOneChat && (_text!=nil && ![_text isEqualToString:@""]))
linphone_chat_message_add_text_content(_message, [_text UTF8String]);
@ -125,17 +126,16 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
[LinphoneManager setValueInMessageAppData:name forKey:key inMessage:_message];
if (voiceContent)
linphone_chat_message_add_content(_message, voiceContent);
LOGI(@"%p Uploading content from message %p", self, _message);
linphone_chat_message_send(_message);
}
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom andVoiceContent:(LinphoneContent *)voiceContent{
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom rootMessage:(LinphoneChatMessage *)rootMessage{
[LinphoneManager.instance.fileTransferDelegates addObject:self];
_message = linphone_chat_room_create_empty_message(chatRoom);
_message = rootMessage;
NSMutableArray<NSString *> *names = [[NSMutableArray alloc] init];
NSMutableArray<NSString *> *types = [[NSMutableArray alloc] init];
@ -165,8 +165,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
// todo indication progress
[LinphoneManager setValueInMessageAppData:names forKey:@"multiparts" inMessage:_message];
[LinphoneManager setValueInMessageAppData:types forKey:@"multipartstypes" inMessage:_message];
if (voiceContent)
linphone_chat_message_add_content(_message, voiceContent);
LOGI(@"%p Uploading content from message %p", self, _message);
linphone_chat_message_send(_message);
}
@ -175,21 +174,17 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
- (void)uploadImage:(UIImage *)image forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality {
NSString *name = [NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]];
NSData *data = UIImageJPEGRepresentation(image, quality);
[self uploadData:data forChatRoom:chatRoom type:@"image" subtype:@"jpg" name:name key:@"localimage" voiceContent:nil];
[self uploadData:data forChatRoom:chatRoom type:@"image" subtype:@"jpg" name:name key:@"localimage" rootMessage:nil];
}
- (void)uploadVideo:(NSData *)data withassetId:(NSString *)phAssetId forChatRoom:(LinphoneChatRoom *)chatRoom {
NSString *name = [NSString stringWithFormat:@"IMG-%f.MOV", [NSDate timeIntervalSinceReferenceDate]];
[self uploadData:data forChatRoom:chatRoom type:@"video" subtype:@"mov" name:name key:@"localvideo" voiceContent:nil];
}
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name {
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name rootMessage:(LinphoneChatMessage *)rootMessage {
NSURL *url = [ChatConversationView getFileUrl:name];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file";
NSString *key = [ChatConversationView getKeyFromFileType:fileType fileName:name];
[self uploadData:data forChatRoom:chatRoom type:fileType subtype:name.lastPathComponent name:name key:key voiceContent:nil];
[self uploadData:data forChatRoom:chatRoom type:fileType subtype:name.lastPathComponent name:name key:key rootMessage:rootMessage];
}
- (BOOL)download:(LinphoneChatMessage *)message {

View file

@ -74,6 +74,13 @@ typedef enum {
@end
@interface UIImageView (ImageWithTint)
- (void)setImageNamed:(NSString *)name tintColor:(UIColor *)color;
- (void)setImageNamed:(NSString *)name tintColorLetter:(NSString *)letter;
@end
@interface NSString (linphoneExt)
- (NSString *)md5;
@ -111,6 +118,8 @@ typedef enum {
- (UIColor *)darkerColor;
+(UIColor *)color:(NSString *)letter;
@end
@interface UIImage (ForceDecode)

View file

@ -575,6 +575,23 @@
@end
@implementation UIImageView (ImageWithTint)
- (void)setImageNamed:(NSString *)name tintColor:(UIColor *)color {
self.image = [[UIImage imageNamed:name] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.tintColor = color;
}
- (void)setImageNamed:(NSString *)name tintColorLetter:(NSString *)letter {
UIColor *color = [UIColor color:letter];
self.image = [[UIImage imageNamed:name] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.tintColor = color;
}
@end
@implementation NSString (md5)
- (NSString *)md5 {
@ -804,6 +821,19 @@
return [self lumColor:0.75];
}
static NSMutableDictionary *letterColors = nil;
+(UIColor *)color:(NSString *)letter {
if (letterColors == nil)
letterColors = [[NSMutableDictionary alloc] init];
if (![letterColors objectForKey:letter]) {
UIImage *colorImage = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/color_%@.png",[[NSBundle mainBundle] bundlePath],letter]];
[letterColors setObject:[UIColor colorWithPatternImage:colorImage] forKey:letter];
}
return [letterColors objectForKey:letter];
}
@end
@implementation UIImage (ForceDecode)

View file

@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
def all_pods
if ENV['PODFILE_PATH'].nil?
pod 'linphone-sdk', '~> 5.1.0-alpha.11+950fc62'
pod 'linphone-sdk', '5.1.0-alpha.50+724b895'
else
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -686,6 +686,18 @@
C64A85522667B74100252AD2 /* ephemeral_messages_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C64A85512667B74100252AD2 /* ephemeral_messages_default.png */; };
C666756F264C925800A0273C /* VFSUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6DA657B261C950C0020CB43 /* VFSUtil.swift */; };
C6667571264C925B00A0273C /* VFSUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6DA657B261C950C0020CB43 /* VFSUtil.swift */; };
C66B03BB26E8EB1A009B5EDC /* UIChatReplyBubbleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C66B03BD26E8EB1A009B5EDC /* UIChatReplyBubbleView.xib */; };
C66B040A26EFDA55009B5EDC /* reply_cancel.png in Resources */ = {isa = PBXBuildFile; fileRef = C66B040926EFDA54009B5EDC /* reply_cancel.png */; };
C66B040E26F095D1009B5EDC /* cancel_forward.png in Resources */ = {isa = PBXBuildFile; fileRef = C66B040D26F095CE009B5EDC /* cancel_forward.png */; };
C6A1BB3526E8815400540D50 /* menu_info.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB3126E8815300540D50 /* menu_info.png */; };
C6A1BB3626E8815400540D50 /* menu_forward_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB3226E8815400540D50 /* menu_forward_default.png */; };
C6A1BB3726E8815400540D50 /* menu_copy_text_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB3326E8815400540D50 /* menu_copy_text_default.png */; };
C6A1BB3826E8815400540D50 /* menu_reply_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB3426E8815400540D50 /* menu_reply_default.png */; };
C6A1BB3A26E881E100540D50 /* menu_delete.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB3926E881E100540D50 /* menu_delete.png */; };
C6A1BB3E26E882D000540D50 /* UIChatReplyBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A1BB3C26E882D000540D50 /* UIChatReplyBubbleView.m */; };
C6A1BB4126E889AD00540D50 /* forward_message_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB4026E889AD00540D50 /* forward_message_default.png */; };
C6A1BB4326E88F7C00540D50 /* menu_resend_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB4226E88F7C00540D50 /* menu_resend_default.png */; };
C6A1BB4526E890BD00540D50 /* file_voice_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6A1BB4426E890BD00540D50 /* file_voice_default.png */; };
C6B4444226AAD0980076C517 /* file_video_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B4443D26AAD0970076C517 /* file_video_default.png */; };
C6B4444326AAD0980076C517 /* file_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B4443E26AAD0970076C517 /* file_default.png */; };
C6B4444426AAD0980076C517 /* file_picture_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B4443F26AAD0970076C517 /* file_picture_default.png */; };
@ -1736,6 +1748,21 @@
C64A854D2667B67200252AD2 /* EphemeralSettingsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EphemeralSettingsView.m; sourceTree = "<group>"; };
C64A854F2667B67A00252AD2 /* EphemeralSettingsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EphemeralSettingsView.xib; sourceTree = "<group>"; };
C64A85512667B74100252AD2 /* ephemeral_messages_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ephemeral_messages_default.png; sourceTree = "<group>"; };
C66B03BC26E8EB1A009B5EDC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatReplyBubbleView.xib; sourceTree = "<group>"; };
C66B03C126E8EB82009B5EDC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/UIChatReplyBubbleView.strings; sourceTree = "<group>"; };
C66B03C326E8EB87009B5EDC /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIChatReplyBubbleView.strings; sourceTree = "<group>"; };
C66B040926EFDA54009B5EDC /* reply_cancel.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reply_cancel.png; sourceTree = "<group>"; };
C66B040D26F095CE009B5EDC /* cancel_forward.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cancel_forward.png; sourceTree = "<group>"; };
C6A1BB3126E8815300540D50 /* menu_info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_info.png; sourceTree = "<group>"; };
C6A1BB3226E8815400540D50 /* menu_forward_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_forward_default.png; sourceTree = "<group>"; };
C6A1BB3326E8815400540D50 /* menu_copy_text_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_copy_text_default.png; sourceTree = "<group>"; };
C6A1BB3426E8815400540D50 /* menu_reply_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_reply_default.png; sourceTree = "<group>"; };
C6A1BB3926E881E100540D50 /* menu_delete.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_delete.png; sourceTree = "<group>"; };
C6A1BB3B26E882D000540D50 /* UIChatReplyBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatReplyBubbleView.h; sourceTree = "<group>"; };
C6A1BB3C26E882D000540D50 /* UIChatReplyBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatReplyBubbleView.m; sourceTree = "<group>"; };
C6A1BB4026E889AD00540D50 /* forward_message_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = forward_message_default.png; sourceTree = "<group>"; };
C6A1BB4226E88F7C00540D50 /* menu_resend_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_resend_default.png; sourceTree = "<group>"; };
C6A1BB4426E890BD00540D50 /* file_voice_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = file_voice_default.png; sourceTree = "<group>"; };
C6B4443D26AAD0970076C517 /* file_video_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = file_video_default.png; sourceTree = "<group>"; };
C6B4443E26AAD0970076C517 /* file_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = file_default.png; sourceTree = "<group>"; };
C6B4443F26AAD0970076C517 /* file_picture_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = file_picture_default.png; sourceTree = "<group>"; };
@ -2190,6 +2217,9 @@
2214EB7012F84668002A5394 /* LinphoneUI */ = {
isa = PBXGroup;
children = (
C6A1BB3B26E882D000540D50 /* UIChatReplyBubbleView.h */,
C6A1BB3C26E882D000540D50 /* UIChatReplyBubbleView.m */,
C66B03BD26E8EB1A009B5EDC /* UIChatReplyBubbleView.xib */,
63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */,
63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */,
63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */,
@ -2471,6 +2501,16 @@
633FEBE11D3CD5570014B822 /* images */ = {
isa = PBXGroup;
children = (
C66B040D26F095CE009B5EDC /* cancel_forward.png */,
C66B040926EFDA54009B5EDC /* reply_cancel.png */,
C6A1BB4426E890BD00540D50 /* file_voice_default.png */,
C6A1BB4226E88F7C00540D50 /* menu_resend_default.png */,
C6A1BB4026E889AD00540D50 /* forward_message_default.png */,
C6A1BB3926E881E100540D50 /* menu_delete.png */,
C6A1BB3326E8815400540D50 /* menu_copy_text_default.png */,
C6A1BB3226E8815400540D50 /* menu_forward_default.png */,
C6A1BB3126E8815300540D50 /* menu_info.png */,
C6A1BB3426E8815400540D50 /* menu_reply_default.png */,
C6B4444026AAD0970076C517 /* file_audio_default.png */,
C6B4443E26AAD0970076C517 /* file_default.png */,
C6B4444126AAD0970076C517 /* file_pdf_default.png */,
@ -3414,6 +3454,7 @@
633FEF3F1D3CD55A0014B822 /* security_pending@2x.png in Resources */,
24BFAAA4209B0630004F47A7 /* linphone_logo.png in Resources */,
633FEDC41D3CD5590014B822 /* call_hangup_disabled.png in Resources */,
C66B03BB26E8EB1A009B5EDC /* UIChatReplyBubbleView.xib in Resources */,
633FEDA81D3CD5590014B822 /* backspace_default.png in Resources */,
636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */,
8CBD7BA620B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib in Resources */,
@ -3480,6 +3521,7 @@
633FEF331D3CD55A0014B822 /* route_speaker_selected@2x.png in Resources */,
633FEE6C1D3CD5590014B822 /* footer_dialer_disabled.png in Resources */,
633FEF231D3CD55A0014B822 /* route_bluetooth_default@2x.png in Resources */,
C6A1BB4526E890BD00540D50 /* file_voice_default.png in Resources */,
633FED9C1D3CD5590014B822 /* add_field_default.png in Resources */,
633FEE411D3CD5590014B822 /* contacts_all_selected@2x.png in Resources */,
D38187F815FE355D00C3EDCA /* TabBarView.xib in Resources */,
@ -3554,6 +3596,7 @@
633FEEED1D3CD55A0014B822 /* numpad_hash_over.png in Resources */,
633FEE1F1D3CD5590014B822 /* chat_start_body_disabled@2x.png in Resources */,
633FEEF81D3CD55A0014B822 /* numpad_star_over~ipad.png in Resources */,
C6A1BB3826E8815400540D50 /* menu_reply_default.png in Resources */,
633FEF301D3CD55A0014B822 /* route_speaker_disabled.png in Resources */,
639CEAFD1A1DF4D9004DE38F /* StatusBarView.xib in Resources */,
633FEDE91D3CD5590014B822 /* call_status_missed~ipad@2x.png in Resources */,
@ -3587,6 +3630,7 @@
633FEEC81D3CD55A0014B822 /* numpad_5_over~ipad@2x.png in Resources */,
61586B91217A175D0038AC45 /* menu_recordings.png in Resources */,
633FEF1B1D3CD55A0014B822 /* presence_away@2x.png in Resources */,
C6A1BB3A26E881E100540D50 /* menu_delete.png in Resources */,
633FEE281D3CD5590014B822 /* checkbox_unchecked.png in Resources */,
633FEE9D1D3CD55A0014B822 /* numpad_0_over.png in Resources */,
633FEEC21D3CD55A0014B822 /* numpad_4~ipad@2x.png in Resources */,
@ -3603,6 +3647,7 @@
633FEEC01D3CD55A0014B822 /* numpad_4_over~ipad@2x.png in Resources */,
61586B8B217A17320038AC45 /* menu_link_account@2x.png in Resources */,
63CDC4661C3BDE370085F529 /* shortring.caf in Resources */,
C6A1BB4126E889AD00540D50 /* forward_message_default.png in Resources */,
633FEDD51D3CD5590014B822 /* call_quality_indicator_4@2x.png in Resources */,
633FEDE71D3CD5590014B822 /* call_status_missed@2x.png in Resources */,
615A2821217F6FBF0060F920 /* security_alert_indicator@2x.png in Resources */,
@ -3733,6 +3778,7 @@
24BFAAA5209B0630004F47A7 /* contacts_sip_default.png in Resources */,
633FEF441D3CD55A0014B822 /* speaker_default.png in Resources */,
639CEB031A1DF4EB004DE38F /* UICompositeView.xib in Resources */,
C6A1BB4326E88F7C00540D50 /* menu_resend_default.png in Resources */,
633FEF3A1D3CD55A0014B822 /* security_ko.png in Resources */,
615A283A2180788E0060F920 /* security_toogle_button.png in Resources */,
633FEDA01D3CD5590014B822 /* avatar.png in Resources */,
@ -3764,6 +3810,7 @@
63CDC45E1C3BDE370085F529 /* msg.caf in Resources */,
633FEE6D1D3CD5590014B822 /* footer_dialer_disabled@2x.png in Resources */,
633FEF171D3CD55A0014B822 /* pause_small_disabled@2x.png in Resources */,
C6A1BB3626E8815400540D50 /* menu_forward_default.png in Resources */,
D38187DD15FE348A00C3EDCA /* AssistantView.xib in Resources */,
633FEDA61D3CD5590014B822 /* back_disabled.png in Resources */,
633FEED61D3CD55A0014B822 /* numpad_7_over@2x.png in Resources */,
@ -3879,6 +3926,7 @@
C6B4444226AAD0980076C517 /* file_video_default.png in Resources */,
633FEDBE1D3CD5590014B822 /* call_back_default.png in Resources */,
633FEF0F1D3CD55A0014B822 /* pause_big_default@2x.png in Resources */,
C66B040E26F095D1009B5EDC /* cancel_forward.png in Resources */,
CF7602F6210898CC00749F76 /* rec_on_default@2x.png in Resources */,
633FEF081D3CD55A0014B822 /* options_start_conference_disabled.png in Resources */,
63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */,
@ -3908,6 +3956,7 @@
633FEE221D3CD5590014B822 /* chat_start_body_over.png in Resources */,
633FEE601D3CD5590014B822 /* edit_list_disabled.png in Resources */,
D38187C115FE345B00C3EDCA /* DialerView.xib in Resources */,
C6A1BB3726E8815400540D50 /* menu_copy_text_default.png in Resources */,
D37EE10D16035793003608A6 /* ImageView.xib in Resources */,
633FEE9F1D3CD55A0014B822 /* numpad_0_over~ipad.png in Resources */,
633FEED51D3CD55A0014B822 /* numpad_7_over.png in Resources */,
@ -3923,6 +3972,7 @@
633FEE4A1D3CD5590014B822 /* delete_disabled.png in Resources */,
614D09CE21E74D5400C43EDF /* GoogleService-Info.plist in Resources */,
C6B4444526AAD0980076C517 /* file_audio_default.png in Resources */,
C6A1BB3526E8815400540D50 /* menu_info.png in Resources */,
C61B1BF72667EC6B001A4E4A /* ephemeral_messages_color_A.png in Resources */,
633FEF151D3CD55A0014B822 /* pause_small_default@2x.png in Resources */,
633FEEF91D3CD55A0014B822 /* numpad_star_over~ipad@2x.png in Resources */,
@ -3997,6 +4047,7 @@
633FEDDD1D3CD5590014B822 /* call_start_body_disabled~ipad@2x.png in Resources */,
633FEEBD1D3CD55A0014B822 /* numpad_4_over.png in Resources */,
8CA70AD41F9E285C00A3D2EB /* chat_group_add@2x.png in Resources */,
C66B040A26EFDA55009B5EDC /* reply_cancel.png in Resources */,
633FEEF11D3CD55A0014B822 /* numpad_hash~ipad.png in Resources */,
633FEE781D3CD5590014B822 /* history_chat_indicator.png in Resources */,
633FEF431D3CD55A0014B822 /* select_all_disabled@2x.png in Resources */,
@ -4275,6 +4326,7 @@
CF7602D7210867E800749F76 /* RecordingsListView.m in Sources */,
63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */,
D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */,
C6A1BB3E26E882D000540D50 /* UIChatReplyBubbleView.m in Sources */,
6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */,
6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */,
D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */,
@ -4764,6 +4816,16 @@
name = UIChatCreateCollectionViewCell.xib;
sourceTree = "<group>";
};
C66B03BD26E8EB1A009B5EDC /* UIChatReplyBubbleView.xib */ = {
isa = PBXVariantGroup;
children = (
C66B03BC26E8EB1A009B5EDC /* Base */,
C66B03C126E8EB82009B5EDC /* en */,
C66B03C326E8EB87009B5EDC /* fr */,
);
name = UIChatReplyBubbleView.xib;
sourceTree = "<group>";
};
D37EE11016035793003608A6 /* ImageView.xib */ = {
isa = PBXVariantGroup;
children = (
@ -4997,7 +5059,7 @@
"-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE",
"$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.11+950fc62\\\"",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.50+724b895\\\"",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5120,7 +5182,7 @@
"-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE",
"$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.11+950fc62\\\"",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.50+724b895\\\"",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5242,7 +5304,7 @@
"-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE",
"$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.11+950fc62\\\"",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.50+724b895\\\"",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5363,7 +5425,7 @@
"-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE",
"$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.11+950fc62\\\"",
"-DLINPHONE_SDK_VERSION=\\\"5.1.0-alpha.50+724b895\\\"",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;