diff --git a/Ring/Ring/Calls/Conference/ContactPickerViewController.storyboard b/Ring/Ring/Calls/Conference/ContactPickerViewController.storyboard
index 2e3931788061ce2c6309f11b883cfab0e260ed05..b709a859d5d7dafde30dbd824eb4c8c7d3cc3bf9 100644
--- a/Ring/Ring/Calls/Conference/ContactPickerViewController.storyboard
+++ b/Ring/Ring/Calls/Conference/ContactPickerViewController.storyboard
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ZwP-Qn-oLY">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ZwP-Qn-oLY">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -11,7 +11,7 @@
         <!--Contact Picker View Controller-->
         <scene sceneID="QZd-Vi-EyD">
             <objects>
-                <viewController modalPresentationStyle="overCurrentContext" id="ZwP-Qn-oLY" customClass="ContactPickerViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController">
+                <viewController extendedLayoutIncludesOpaqueBars="YES" modalPresentationStyle="overFullScreen" id="ZwP-Qn-oLY" customClass="ContactPickerViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController">
                     <view key="view" contentMode="scaleToFill" id="TtT-WG-OAE">
                         <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -40,10 +40,16 @@
                             <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="Bdz-kj-0K4">
                                 <rect key="frame" x="0.0" y="44" width="414" height="818"/>
                                 <subviews>
+                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LZ0-vA-uc5">
+                                        <rect key="frame" x="182" y="0.0" width="50" height="50"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="50" id="C1b-Mo-dnW"/>
+                                        </constraints>
+                                    </view>
                                     <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cfK-DS-kt1">
-                                        <rect key="frame" x="0.0" y="0.0" width="414" height="90"/>
+                                        <rect key="frame" x="0.0" y="50" width="414" height="90"/>
                                         <subviews>
-                                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6AM-a0-weG">
+                                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6AM-a0-weG">
                                                 <rect key="frame" x="364" y="45" width="30" height="35"/>
                                                 <fontDescription key="fontDescription" type="system" pointSize="19"/>
                                             </button>
@@ -55,7 +61,7 @@
                                         </constraints>
                                     </view>
                                     <searchBar contentMode="redraw" searchBarStyle="prominent" showsSearchResultsButton="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ht5-JP-L4t">
-                                        <rect key="frame" x="0.0" y="90" width="414" height="44"/>
+                                        <rect key="frame" x="0.0" y="140" width="414" height="44"/>
                                         <constraints>
                                             <constraint firstAttribute="height" constant="44" id="Ott-Go-5mf"/>
                                         </constraints>
@@ -63,7 +69,7 @@
                                         <textInputTraits key="textInputTraits"/>
                                     </searchBar>
                                     <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsMultipleSelection="YES" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="i1P-Li-H82">
-                                        <rect key="frame" x="0.0" y="134" width="414" height="684"/>
+                                        <rect key="frame" x="0.0" y="184" width="414" height="634"/>
                                         <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                         <connections>
                                             <outlet property="delegate" destination="ZwP-Qn-oLY" id="EoQ-WF-bN4"/>
@@ -71,7 +77,6 @@
                                     </tableView>
                                 </subviews>
                                 <constraints>
-                                    <constraint firstItem="cfK-DS-kt1" firstAttribute="top" secondItem="Bdz-kj-0K4" secondAttribute="top" id="4Ai-6C-pS6"/>
                                     <constraint firstAttribute="trailing" secondItem="i1P-Li-H82" secondAttribute="trailing" id="4SM-vM-mgc"/>
                                     <constraint firstAttribute="bottom" secondItem="i1P-Li-H82" secondAttribute="bottom" id="MtY-d8-Qac"/>
                                     <constraint firstItem="cfK-DS-kt1" firstAttribute="leading" secondItem="Bdz-kj-0K4" secondAttribute="leading" id="RVA-PE-P1b"/>
@@ -82,6 +87,7 @@
                                 </constraints>
                             </stackView>
                         </subviews>
+                        <viewLayoutGuide key="safeArea" id="HLr-8o-AJK"/>
                         <constraints>
                             <constraint firstItem="VI3-Wm-odB" firstAttribute="top" secondItem="Bdz-kj-0K4" secondAttribute="top" id="0qq-2Q-k11"/>
                             <constraint firstItem="VI3-Wm-odB" firstAttribute="leading" secondItem="Bdz-kj-0K4" secondAttribute="leading" id="5pC-zY-2Vk"/>
@@ -92,12 +98,12 @@
                             <constraint firstItem="HLr-8o-AJK" firstAttribute="bottom" secondItem="VI3-Wm-odB" secondAttribute="bottom" id="l3e-iB-s2n"/>
                             <constraint firstItem="VI3-Wm-odB" firstAttribute="trailing" secondItem="Bdz-kj-0K4" secondAttribute="trailing" id="sVI-Ny-tp3"/>
                         </constraints>
-                        <viewLayoutGuide key="safeArea" id="HLr-8o-AJK"/>
                     </view>
                     <connections>
                         <outlet property="doneButton" destination="6AM-a0-weG" id="2yX-Fh-qwe"/>
                         <outlet property="searchBar" destination="ht5-JP-L4t" id="adL-r1-B3M"/>
                         <outlet property="tableView" destination="i1P-Li-H82" id="Hbd-c3-3WV"/>
+                        <outlet property="topSpace" destination="C1b-Mo-dnW" id="0UO-Q0-o1H"/>
                         <outlet property="topViewContainer" destination="cfK-DS-kt1" id="s5H-k8-YXw"/>
                     </connections>
                 </viewController>
diff --git a/Ring/Ring/Calls/Conference/ContactPickerViewController.swift b/Ring/Ring/Calls/Conference/ContactPickerViewController.swift
index 8c85ad9655ad6ab15ba5a8170cd058957ecf1a46..1ceca8c4388571912b9e846008c5ce9ba43d0146 100644
--- a/Ring/Ring/Calls/Conference/ContactPickerViewController.swift
+++ b/Ring/Ring/Calls/Conference/ContactPickerViewController.swift
@@ -37,6 +37,7 @@ class ContactPickerViewController: UIViewController, StoryboardBased, ViewModelB
     @IBOutlet weak var tableView: UITableView!
     @IBOutlet weak var doneButton: UIButton!
     @IBOutlet weak var topViewContainer: UIView!
+    @IBOutlet weak var topSpace: NSLayoutConstraint!
 
     var viewModel: ContactPickerViewModel!
     private let disposeBag = DisposeBag()
@@ -224,6 +225,7 @@ class ContactPickerViewController: UIViewController, StoryboardBased, ViewModelB
             let dismissGR = UISwipeGestureRecognizer(target: self, action: #selector(remove(gesture:)))
             dismissGR.direction = UISwipeGestureRecognizer.Direction.down
             dismissGR.delegate = self
+            topSpace.constant = 0
             self.searchBar.addGestureRecognizer(dismissGR)
             self.rowSelectionHandler = { [weak self] row in
                 guard let self = self else { return }
@@ -236,6 +238,7 @@ class ContactPickerViewController: UIViewController, StoryboardBased, ViewModelB
             self.searchBar.backgroundColor = UIColor.clear
             self.doneButton.setTitle(L10n.Actions.cancelAction, for: .normal)
             self.doneButton.setTitleColor(UIColor.jamiTextBlue, for: .normal)
+            topSpace.constant = 50
             self.doneButton.rx.tap
                 .subscribe(onNext: { [weak self] in
                     let paths = self?.tableView.indexPathsForSelectedRows
diff --git a/Ring/Ring/Constants/Generated/Images.swift b/Ring/Ring/Constants/Generated/Images.swift
index f346b31378146f3f63df729a0317903168303904..adc0e747356c78e476ef5c9790f57ca1b30ba0e9 100644
--- a/Ring/Ring/Constants/Generated/Images.swift
+++ b/Ring/Ring/Constants/Generated/Images.swift
@@ -50,7 +50,10 @@ internal enum Asset {
   internal static let icBack = ImageAsset(name: "ic_back")
   internal static let icContactPicture = ImageAsset(name: "ic_contact_picture")
   internal static let icConversationRemove = ImageAsset(name: "ic_conversation_remove")
+  internal static let icForward = ImageAsset(name: "ic_forward")
   internal static let icHideInput = ImageAsset(name: "ic_hide_input")
+  internal static let icSave = ImageAsset(name: "ic_save")
+  internal static let icShare = ImageAsset(name: "ic_share")
   internal static let icShowInput = ImageAsset(name: "ic_show_input")
   internal static let infoArrow = ImageAsset(name: "info_arrow")
   internal static let jamiIcon = ImageAsset(name: "jamiIcon")
diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift
index 532c2bb4e76329113b28c6358622b87278c4611d..17e9c272b6b564347cd6f63c01f17823c5badb44 100644
--- a/Ring/Ring/Constants/Generated/Strings.swift
+++ b/Ring/Ring/Constants/Generated/Strings.swift
@@ -321,6 +321,8 @@ internal enum L10n {
   }
 
   internal enum Conversation {
+    /// Failed to save image to galery
+    internal static let errorSavingImage = L10n.tr("Localizable", "conversation.errorSavingImage")
     /// You are currently receiving a live location from 
     internal static let explanationReceivingLocationFrom = L10n.tr("Localizable", "conversation.explanationReceivingLocationFrom")
     /// You are currently sharing your location with 
@@ -451,12 +453,20 @@ internal enum L10n {
     internal static let close = L10n.tr("Localizable", "global.close")
     /// Invitations
     internal static let contactRequestsTabBarTitle = L10n.tr("Localizable", "global.contactRequestsTabBarTitle")
+    /// Forward
+    internal static let forward = L10n.tr("Localizable", "global.forward")
     /// Conversations
     internal static let homeTabBarTitle = L10n.tr("Localizable", "global.homeTabBarTitle")
     /// Account
     internal static let meTabBarTitle = L10n.tr("Localizable", "global.meTabBarTitle")
     /// Ok
     internal static let ok = L10n.tr("Localizable", "global.ok")
+    /// Preview
+    internal static let preview = L10n.tr("Localizable", "global.preview")
+    /// Resend
+    internal static let resend = L10n.tr("Localizable", "global.resend")
+    /// Save
+    internal static let save = L10n.tr("Localizable", "global.save")
     /// Share
     internal static let share = L10n.tr("Localizable", "global.share")
     /// Together
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
index c54f98c387999300fcceea55c0813f2d2d4cd388..36579cbc4e965f387755f2eec282e059aec2806a 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
@@ -30,8 +30,7 @@ import SwiftyBeaver
 
 // swiftlint:disable type_body_length
 // swiftlint:disable file_length
-class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
-
+class MessageCell: UITableViewCell, NibReusable, PlayerDelegate, PreviewViewControllerDelegate {
     // MARK: Properties
 
     let log = SwiftyBeaver.self
@@ -76,10 +75,17 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
     private(set) var messageId: Int64?
     private var isCopyable: Bool = false
     private var couldBeShared: Bool = false
+    private var couldBeResend: Bool = false
+    private var couldBeForward: Bool = false
+    private var couldBeSaved: Bool = false
     private let _deleteMessage = BehaviorRelay<Bool>(value: false)
     var deleteMessage: Observable<Bool> { _deleteMessage.asObservable() }
 
     var shareMessage = PublishSubject<Bool>()
+    var forwardMessage = PublishSubject<Bool>()
+    var saveMessage = PublishSubject<Bool>()
+    var resendMessage = PublishSubject<Bool>()
+    var previewMessage = PublishSubject<Bool>()
 
     private let showTimeTap = BehaviorRelay<Bool>(value: false)
     var tappedToShowTime: Observable<Bool> { showTimeTap.asObservable() }
@@ -134,6 +140,8 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         self.messageId = nil
         self.isCopyable = false
         self.couldBeShared = false
+        self.couldBeResend = false
+        self.couldBeForward = false
         self._deleteMessage.accept(false)
         if let longGestureRecognizer = longGestureRecognizer {
             self.bubble.removeGestureRecognizer(longGestureRecognizer)
@@ -207,21 +215,17 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         }
     }
 
-    func supportFullScreenMode() -> Bool {
-        return (playerView != nil && playerView!.viewModel.hasVideo.value) || self.transferImageView.image != nil
-    }
-
     // MARK: Configure
 
     func configureTapGesture() {
-        let shownByDefault = !self.timeLabel.isHidden && !showTimeTap.value && !supportFullScreenMode()
+        let shownByDefault = !self.timeLabel.isHidden && !showTimeTap.value && !self.couldBeShared
         if shownByDefault { return }
         self.bubble.isUserInteractionEnabled = true
         self.tapGestureRecognizer = UITapGestureRecognizer()
         self.tapGestureRecognizer?.numberOfTapsRequired = 1
         self.tapGestureRecognizer?.delegate = self
         self.tapGestureRecognizer!.rx.event.bind(onNext: { [weak self] _ in self?.onTapGesture() }).disposed(by: self.disposeBag)
-        self.tapGestureRecognizer!.cancelsTouchesInView = supportFullScreenMode() ? true : false
+        self.tapGestureRecognizer!.cancelsTouchesInView = self.couldBeShared ? true : false
         self.bubble.addGestureRecognizer(tapGestureRecognizer!)
         guard let doubleTap = doubleTapGestureRecognizer else { return }
         self.tapGestureRecognizer?.require(toFail: doubleTap)
@@ -245,7 +249,7 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
 
     func onTapGesture() {
         // for player or image expand size on tap, for other messages show time
-        if supportFullScreenMode() {
+        if self.couldBeShared {
             openPreview.accept(true)
             return
         }
@@ -261,10 +265,13 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         self.showTimeTap.accept(true)
     }
 
-    private func configureLongGesture(_ messageId: Int64, _ bubblePosition: BubblePosition, _ isTransfer: Bool, _ isLocationSharingBubble: Bool) {
+    private func configureLongGesture(_ messageId: Int64, _ bubblePosition: BubblePosition, _ isTransfer: Bool, _ isLocationSharingBubble: Bool, isTransferSuccess: Bool, isError: Bool) {
         self.messageId = messageId
         self.isCopyable = bubblePosition != .generated && !isTransfer && !isLocationSharingBubble
-        self.couldBeShared = bubblePosition != .generated && !isLocationSharingBubble
+        self.couldBeShared = isTransfer && isTransferSuccess
+        self.couldBeForward = bubblePosition != .generated && !isLocationSharingBubble && (isTransferSuccess || !isTransfer)
+        self.couldBeResend = isError && bubblePosition == .sent
+        self.couldBeSaved = self.couldBeShared && self.transferedImage != nil
         self.bubble.isUserInteractionEnabled = true
         longGestureRecognizer = UILongPressGestureRecognizer()
         longGestureRecognizer!.rx.event.bind(onNext: { [weak self] _ in self?.onLongGesture() }).disposed(by: self.disposeBag)
@@ -275,7 +282,11 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         becomeFirstResponder()
         let menu = UIMenuController.shared
         let shareItem = UIMenuItem(title: L10n.Global.share, action: NSSelectorFromString("share"))
-        menu.menuItems = [shareItem]
+        let forwardItem = UIMenuItem(title: L10n.Global.forward, action: NSSelectorFromString("forward"))
+        let saveItem = UIMenuItem(title: L10n.Global.save, action: NSSelectorFromString("save"))
+        let resendItem = UIMenuItem(title: L10n.Global.resend, action: NSSelectorFromString("resend"))
+        let previewItem = UIMenuItem(title: L10n.Global.preview, action: NSSelectorFromString("preview"))
+        menu.menuItems = [previewItem, shareItem, forwardItem, saveItem, resendItem]
         if !menu.isMenuVisible {
             menu.setTargetRect(self.bubble.frame, in: self)
             menu.setMenuVisible(true, animated: true)
@@ -287,6 +298,42 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         shareMessage.onNext(true)
     }
 
+    @objc
+    func forward() {
+        forwardMessage.onNext(true)
+    }
+
+    @objc
+    func save() {
+        saveMessage.onNext(true)
+    }
+
+    @objc
+    func resend() {
+        resendMessage.onNext(true)
+    }
+
+    @objc
+    func preview() {
+        previewMessage.onNext(true)
+    }
+
+    func deleteFile() {
+        _deleteMessage.accept(true)
+    }
+
+    func shareFile() {
+        shareMessage.onNext(true)
+    }
+
+    func forwardFile() {
+        forwardMessage.onNext(true)
+    }
+
+    func saveFile() {
+        saveMessage.onNext(true)
+    }
+
     override func copy(_ sender: Any?) {
         UIPasteboard.general.string = self.messageLabel?.text
         UIMenuController.shared.setMenuVisible(false, animated: true)
@@ -302,7 +349,12 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
 
     override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
         return action == #selector(UIResponderStandardEditActions.copy) && self.isCopyable ||
-            action == #selector(UIResponderStandardEditActions.delete) || (action == NSSelectorFromString("share") && self.couldBeShared)
+            action == #selector(UIResponderStandardEditActions.delete) ||
+            (action == NSSelectorFromString("forward") && self.couldBeForward) ||
+            (action == NSSelectorFromString("share") && self.couldBeShared) ||
+            (action == NSSelectorFromString("resend") && self.couldBeResend) ||
+            (action == NSSelectorFromString("save") && self.couldBeSaved) ||
+            (action == NSSelectorFromString("preview") && self.couldBeShared)
     }
 
     func toggleCellTimeLabelVisibility() {
@@ -441,7 +493,6 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         self.configureCellTimeLabel(item)
 
         self.prepareForReuseLongGesture()
-        self.configureLongGesture(item.message.messageId, item.bubblePosition(), item.isTransfer, item.isLocationSharingBubble)
 
         self.prepareForReuseTapGesture()
 
@@ -522,7 +573,16 @@ class MessageCell: UITableViewCell, NibReusable, PlayerDelegate {
         } else if item.isTransfer {
             self.messageLabelMarginConstraint.constant = -2
         }
-
+        var isError = false
+        if item.isTransfer {
+            isError = item.initialTransferStatus == .error || item.initialTransferStatus == .canceled
+        } else if item.isText {
+            isError = item.message.status == .failure
+        }
+        self.configureLongGesture(item.message.messageId, item.bubblePosition(),
+                                  item.isTransfer, item.isLocationSharingBubble,
+                                  isTransferSuccess: item.initialTransferStatus == .success,
+                                  isError: isError)
         self.configureTapGesture()
     }
 
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index e55a3dd700f4136611b6367d59d245e30a771e6a..efc268fd3704cf9b11af48fe334c7b6ef159d1b6 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -34,7 +34,9 @@ import MobileCoreServices
 // swiftlint:disable type_body_length
 class ConversationViewController: UIViewController,
                                   UIImagePickerControllerDelegate, UINavigationControllerDelegate,
-                                  UIDocumentPickerDelegate, StoryboardBased, ViewModelBased, MessageAccessoryViewDelegate, ContactPickerDelegate, PHPickerViewControllerDelegate {
+                                  UIDocumentPickerDelegate, StoryboardBased, ViewModelBased,
+                                  MessageAccessoryViewDelegate, ContactPickerDelegate,
+                                  PHPickerViewControllerDelegate, UIDocumentInteractionControllerDelegate {
 
     let log = SwiftyBeaver.self
 
@@ -73,18 +75,6 @@ class ConversationViewController: UIViewController,
         self.setupUI()
         self.setupTableView()
         self.setupBindings()
-        NotificationCenter.default.rx
-            .notification(UIDevice.orientationDidChangeNotification)
-            .observeOn(MainScheduler.instance)
-            .subscribe(onNext: {[weak self](_) in
-                guard let self = self,
-                UIDevice.current.portraitOrLandscape else { return }
-                self.setupNavTitle(profileImageData: self.viewModel.profileImageData.value,
-                                   displayName: self.viewModel.displayName.value,
-                                   username: self.viewModel.userName.value)
-                self.tableView.reloadData()
-            })
-            .disposed(by: self.disposeBag)
 
         /*
          Register to keyboard notifications to adjust tableView insets when the keybaord appears
@@ -100,6 +90,22 @@ class ConversationViewController: UIViewController,
         keyboardDismissTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
     }
 
+    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+        // Waiting for screen size change
+        DispatchQueue.global(qos: .background).async {
+            sleep(UInt32(0.5))
+            DispatchQueue.main.async { [weak self] in
+                guard let self = self,
+                UIDevice.current.portraitOrLandscape else { return }
+                self.setupNavTitle(profileImageData: self.viewModel.profileImageData.value,
+                                   displayName: self.viewModel.displayName.value,
+                                   username: self.viewModel.userName.value)
+                self.tableView.reloadData()
+            }
+        }
+        super.viewWillTransition(to: size, with: coordinator)
+    }
+
     @objc
     private func applicationWillResignActive() {
         self.viewModel.setIsComposingMsg(isComposing: false)
@@ -137,6 +143,8 @@ class ConversationViewController: UIViewController,
         self.present(alert, animated: true, completion: nil)
     }
 
+    // MARK: photo library
+
     func checkPhotoLibraryPermission() {
         let status = PHPhotoLibrary.authorizationStatus()
         switch status {
@@ -367,6 +375,19 @@ class ConversationViewController: UIViewController,
             })
     }
 
+    func saveImageToGalery (image: UIImage) {
+        UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
+    }
+
+    @objc
+    func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
+        if let error = error {
+            let allert = UIAlertController(title: L10n.Conversation.errorSavingImage, message: error.localizedDescription, preferredStyle: .alert)
+            allert.addAction(UIAlertAction(title: "OK", style: .default))
+            present(allert, animated: true)
+        }
+    }
+
     @objc
     func dismissKeyboard() {
         self.becomeFirstResponder()
@@ -954,18 +975,38 @@ class ConversationViewController: UIViewController,
             .disposed(by: cell.disposeBag)
     }
 
+    // MARK: open file
+
+    func openDocument(messageModel: MessageViewModel) {
+        let conversation = self.viewModel.conversation.value.conversationId
+        let accountId = self.viewModel.conversation.value.accountId
+        guard let url = messageModel.transferedFile(conversationID: conversation, accountId: accountId),
+              FileManager().fileExists(atPath: url.path) else { return }
+        let interactionController = UIDocumentInteractionController(url: url)
+        interactionController.delegate = self
+        interactionController.presentPreview(animated: true)
+    }
+
+    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
+        if let navigationController = self.navigationController {
+            return navigationController
+        }
+        return self
+    }
+
+    // MARK: open share menu
     func showShareMenu(messageModel: MessageViewModel) {
         let conversation = self.viewModel.conversation.value.conversationId
         let accountId = self.viewModel.conversation.value.accountId
         if let file = messageModel.transferedFile(conversationID: conversation, accountId: accountId) {
-            self.presentActivitycontrollerWithItems(items: [file])
+            self.presentActivityControllerWithItems(items: [file])
             return
         }
         if messageModel
             .getURLFromPhotoLibrary(conversationID: conversation,
                                     completionHandler: { [weak self, weak messageModel] url in
                                         if let url = url {
-                                            self?.presentActivitycontrollerWithItems(items: [url])
+                                            self?.presentActivityControllerWithItems(items: [url])
                                             return
                                         }
                                         guard let messageModel = messageModel else { return }
@@ -980,16 +1021,15 @@ class ConversationViewController: UIViewController,
         if let image = messageModel.getTransferedImage(maxSize: 250,
                                                        conversationID: conversationId,
                                                        accountId: accountId) {
-            self.presentActivitycontrollerWithItems(items: [image])
+            self.presentActivityControllerWithItems(items: [image])
         }
     }
 
-    func presentActivitycontrollerWithItems(items: [Any]) {
+    func presentActivityControllerWithItems(items: [Any]) {
         let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
         activityViewController.popoverPresentationController?.sourceView = self.view
         activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection()
         activityViewController.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.maxX, width: 0, height: 0)
-        activityViewController.excludedActivityTypes = [UIActivity.ActivityType.airDrop]
         self.present(activityViewController, animated: true, completion: nil)
     }
 
@@ -1001,8 +1041,8 @@ class ConversationViewController: UIViewController,
         let screenSize = UIScreen.main.bounds
         let screenWidth = screenSize.width
         let screenHeight = screenSize.height
-        let newFrame = CGRect(x: 0, y: -statusBarHeight, width: screenWidth, height: screenHeight)
-        let initialFrame = CGRect(x: 0, y: screenHeight, width: screenWidth, height: screenHeight)
+        let newFrame = CGRect(x: 0, y: -statusBarHeight, width: screenWidth, height: screenHeight + statusBarHeight)
+        let initialFrame = CGRect(x: 0, y: screenHeight, width: screenWidth, height: screenHeight + statusBarHeight)
         contactPickerVC.view.frame = initialFrame
         self.view.addSubview(contactPickerVC.view)
         contactPickerVC.didMove(toParent: self)
@@ -1063,7 +1103,7 @@ extension ConversationViewController: UITableViewDataSource {
             self.transferCellSetup(item, cell, tableView, indexPath)
             self.locationCellSetup(item, cell)
             self.deleteCellSetup(cell)
-            self.shareMessageCellSeUp(cell, item: item)
+            self.messageCellActionsSetUp(cell, item: item)
             self.tapToShowTimeCellSetup(cell)
 
             return cell
@@ -1089,12 +1129,47 @@ extension ConversationViewController: UITableViewDataSource {
             .disposed(by: cell.disposeBag)
     }
 
-    private func shareMessageCellSeUp(_ cell: MessageCell, item: MessageViewModel) {
+    private func messageCellActionsSetUp(_ cell: MessageCell, item: MessageViewModel) {
         cell.shareMessage
+            .observeOn(MainScheduler.instance)
+            .subscribe(onNext: { [weak self, weak item] (shouldShare) in
+                guard shouldShare, let item = item else { return }
+                self?.showShareMenu(messageModel: item)
+            })
+            .disposed(by: cell.disposeBag)
+        cell.forwardMessage
+            .observeOn(MainScheduler.instance)
+            .subscribe(onNext: { [weak self, weak item] (shouldForward) in
+                guard shouldForward, let item = item else { return }
+                self?.viewModel.slectContactsToShareMessage(message: item)
+            })
+            .disposed(by: cell.disposeBag)
+        cell.saveMessage
+            .observeOn(MainScheduler.instance)
+            .subscribe(onNext: { [weak self, weak cell] (shouldSave) in
+                guard shouldSave, let cell = cell, let image = cell.transferedImage else { return }
+                self?.saveImageToGalery(image: image)
+            })
+            .disposed(by: cell.disposeBag)
+        cell.resendMessage
             .observeOn(MainScheduler.instance)
             .subscribe(onNext: { [weak self, weak item] (shouldResend) in
                 guard shouldResend, let item = item else { return }
-                self?.viewModel.slectContactsToShareMessage(message: item)
+                self?.viewModel.resendMessage(message: item)
+            })
+            .disposed(by: cell.disposeBag)
+        cell.previewMessage
+            .observeOn(MainScheduler.instance)
+            .subscribe(onNext: { [weak self, weak item, weak cell] (shouldPreview) in
+                guard shouldPreview, let item = item, let cell = cell, let self = self, let initialFrame = cell.getInitialFrame() else { return }
+                let player = item.getPlayer(conversationViewModel: self.viewModel)
+                let image = cell.transferedImage
+                if player == nil && image == nil {
+                    self.openDocument(messageModel: item)
+                    return
+                }
+                self.inputAccessoryView.isHidden = true
+                self.viewModel.openFullScreenPreview(parentView: self, viewModel: player, image: image, initialFrame: initialFrame, delegate: cell)
             })
             .disposed(by: cell.disposeBag)
     }
@@ -1196,13 +1271,16 @@ extension ConversationViewController: UITableViewDataSource {
                 .disposed(by: cell.disposeBag)
             cell.openPreview
                 .subscribe(onNext: { [weak self, weak item, weak cell] open in
-                    guard let self = self, open,
-                        let initialFrame = cell?.getInitialFrame() else { return }
-                    let player = item?.getPlayer(conversationViewModel: self.viewModel)
-                    let image = cell?.transferedImage
-                    if player == nil && image == nil { return }
+                    guard let self = self, open, let cell = cell, let item = item,
+                        let initialFrame = cell.getInitialFrame() else { return }
+                    let player = item.getPlayer(conversationViewModel: self.viewModel)
+                    let image = cell.transferedImage
+                    if player == nil && image == nil {
+                        self.openDocument(messageModel: item)
+                        return
+                    }
                     self.inputAccessoryView.isHidden = true
-                    self.viewModel.openFullScreenPreview(parentView: self, viewModel: player, image: image, initialFrame: initialFrame)
+                    self.viewModel.openFullScreenPreview(parentView: self, viewModel: player, image: image, initialFrame: initialFrame, delegate: cell)
                 })
                 .disposed(by: cell.disposeBag)
             cell.playerHeight
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index 932969b547b648413905fee08cf704a4be51e2d9..20f8fd5e9939b41a3396be6cde21805dea41cf95 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -703,8 +703,8 @@ extension ConversationViewModel {
                                                         contactUri: self.conversation.value.participantUri)
     }
 
-    func openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect) {
-        self.stateSubject.onNext(ConversationState.openFullScreenPreview(parentView: parentView, viewModel: viewModel, image: image, initialFrame: initialFrame))
+    func openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect, delegate: PreviewViewControllerDelegate) {
+        self.stateSubject.onNext(ConversationState.openFullScreenPreview(parentView: parentView, viewModel: viewModel, image: image, initialFrame: initialFrame, delegate: delegate))
     }
 }
 
@@ -764,6 +764,36 @@ extension ConversationViewModel {
         self.changeConversationIfNeeded(items: selectedContacts)
     }
 
+    func resendMessage(message: MessageViewModel) {
+        guard !message.message.isGenerated,
+              !message.message.isLocationSharing else { return }
+        if !message.message.isTransfer {
+            self.sendMessage(withContent: message.content, contactURI: conversation.value.participantUri)
+            return
+        }
+        let conversationId = self.conversation.value.conversationId
+        let accountId = self.conversation.value.accountId
+        var fileName = message.content
+        if message.content.contains("\n") {
+            guard let substring = message.content.split(separator: "\n").first else { return }
+            fileName = String(substring)
+        }
+        if let url = message.transferedFile(conversationID: conversationId, accountId: accountId) {
+            self.sendFile(filePath: url.path, displayName: fileName, contactHash: self.conversation.value.hash)
+            return
+        }
+        if let image = message.getTransferedImage(maxSize: 200, conversationID: conversationId, accountId: accountId) {
+            let identifier = message.transferFileData.identifier
+            if identifier != nil {
+                self.sendImageFromPhotoLibraty(image: image, imageName: fileName, localIdentifier: identifier, contactHash: self.conversation.value.hash)
+                return
+            }
+            if let data = image.jpegData(compressionQuality: 100) {
+                self.sendAndSaveFile(displayName: fileName, imageData: data, contactHash: self.conversation.value.hash, conversation: self.conversation.value.conversationId)
+            }
+        }
+    }
+
     func slectContactsToShareMessage(message: MessageViewModel) {
         guard !message.message.isGenerated,
             !message.message.isLocationSharing else { return }
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
index c401b65f908877a902f363761451fae12188d5d8..2ffb909e346bb2161be89c9b6c68383a24b3ec6b 100644
--- a/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
@@ -68,6 +68,7 @@ class MessageViewModel {
     var isComposingIndicator: Bool = false
 
     var isLocationSharingBubble: Bool { return self.message.isLocationSharing }
+    var isText: Bool { return !self.message.isLocationSharing && !self.message.isGenerated && !self.message.isTransfer }
 
     private let disposeBag = DisposeBag()
     let injectBug: InjectionBag
diff --git a/Ring/Ring/Features/Conversations/Preview/PreviewViewController.storyboard b/Ring/Ring/Features/Conversations/Preview/PreviewViewController.storyboard
index eebbc9187d337225a9f60d12bd9c3c849383111a..221f9d69ec5a6831db3d36c82f273f9314843e14 100644
--- a/Ring/Ring/Features/Conversations/Preview/PreviewViewController.storyboard
+++ b/Ring/Ring/Features/Conversations/Preview/PreviewViewController.storyboard
@@ -1,10 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="edr-AU-dxH">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="edr-AU-dxH">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
+        <capability name="Image references" minToolsVersion="12.0"/>
         <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>
     <scenes>
@@ -23,6 +25,41 @@
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kNJ-67-zFf">
                                 <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                             </imageView>
+                            <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="3aB-Lr-pJQ">
+                                <rect key="frame" x="0.0" y="772" width="414" height="90"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Gvs-6O-5Fs">
+                                        <rect key="frame" x="0.0" y="33" width="103.5" height="24"/>
+                                        <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <state key="normal">
+                                            <imageReference key="image" image="ic_share" symbolScale="large"/>
+                                        </state>
+                                    </button>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GFG-Jq-Pqx">
+                                        <rect key="frame" x="103.5" y="31.5" width="103.5" height="27"/>
+                                        <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <state key="normal">
+                                            <imageReference key="image" image="ic_forward" symbolScale="large"/>
+                                        </state>
+                                    </button>
+                                    <button opaque="NO" contentMode="center" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5q1-cC-MI7">
+                                        <rect key="frame" x="207" y="31.5" width="103.5" height="27"/>
+                                        <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <state key="normal" image="ic_save">
+                                            <preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="default"/>
+                                        </state>
+                                    </button>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5pB-7e-B3j">
+                                        <rect key="frame" x="310.5" y="31.5" width="103.5" height="27"/>
+                                        <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <state key="normal" image="ic_conversation_remove"/>
+                                    </button>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.7987211045" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="90" id="BTB-tx-Psf"/>
+                                </constraints>
+                            </stackView>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="umc-Uj-AVs">
                                 <rect key="frame" x="0.0" y="0.0" width="414" height="80"/>
                                 <constraints>
@@ -32,21 +69,25 @@
                             <view contentMode="scaleToFill" id="Jga-0U-qXG" customClass="PlayerView" customModule="Ring" customModuleProvider="target">
                                 <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                             </view>
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="s0z-cK-ISY">
-                                <rect key="frame" x="340" y="44" width="49" height="35"/>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="s0z-cK-ISY">
+                                <rect key="frame" x="341" y="44" width="48" height="35"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="19"/>
                                 <state key="normal" title="Close">
                                     <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 </state>
                             </button>
                         </subviews>
+                        <viewLayoutGuide key="safeArea" id="dJP-6X-zM4"/>
                         <constraints>
                             <constraint firstItem="s0z-cK-ISY" firstAttribute="top" secondItem="dJP-6X-zM4" secondAttribute="top" priority="250" id="0CU-8Q-b0S"/>
+                            <constraint firstItem="3aB-Lr-pJQ" firstAttribute="leading" secondItem="dJP-6X-zM4" secondAttribute="leading" id="26g-Gx-ObU"/>
                             <constraint firstItem="9Qb-6X-Utl" firstAttribute="leading" secondItem="QAC-jd-TeH" secondAttribute="leading" id="39d-qj-71g"/>
                             <constraint firstItem="s0z-cK-ISY" firstAttribute="trailing" secondItem="Jga-0U-qXG" secondAttribute="trailing" constant="-25" id="IcL-2k-lX8"/>
+                            <constraint firstItem="dJP-6X-zM4" firstAttribute="trailing" secondItem="3aB-Lr-pJQ" secondAttribute="trailing" id="Mj0-Nc-ouz"/>
                             <constraint firstItem="Jga-0U-qXG" firstAttribute="top" secondItem="QAC-jd-TeH" secondAttribute="top" id="Ome-jS-TQa"/>
+                            <constraint firstItem="dJP-6X-zM4" firstAttribute="bottom" secondItem="3aB-Lr-pJQ" secondAttribute="bottom" id="QMX-S4-F1Q"/>
                             <constraint firstAttribute="bottom" secondItem="9Qb-6X-Utl" secondAttribute="bottom" id="R1V-fE-JGu"/>
                             <constraint firstItem="umc-Uj-AVs" firstAttribute="top" secondItem="QAC-jd-TeH" secondAttribute="top" id="RVi-sm-LCM"/>
                             <constraint firstItem="umc-Uj-AVs" firstAttribute="leading" secondItem="dJP-6X-zM4" secondAttribute="leading" id="XwX-7d-vQ6"/>
@@ -61,12 +102,14 @@
                             <constraint firstItem="Jga-0U-qXG" firstAttribute="leading" secondItem="dJP-6X-zM4" secondAttribute="leading" id="lQU-Ek-RAG"/>
                             <constraint firstItem="9Qb-6X-Utl" firstAttribute="top" secondItem="QAC-jd-TeH" secondAttribute="top" id="nIf-wb-wOx"/>
                         </constraints>
-                        <viewLayoutGuide key="safeArea" id="dJP-6X-zM4"/>
                     </view>
                     <nil key="simulatedTopBarMetrics"/>
                     <nil key="simulatedBottomBarMetrics"/>
                     <connections>
                         <outlet property="backgroundView" destination="9Qb-6X-Utl" id="nva-VK-fcG"/>
+                        <outlet property="buttonsContainer" destination="3aB-Lr-pJQ" id="u7z-BG-n68"/>
+                        <outlet property="deleteButton" destination="5pB-7e-B3j" id="Fcj-G9-OLd"/>
+                        <outlet property="forwardButton" destination="GFG-Jq-Pqx" id="Vot-bV-hkU"/>
                         <outlet property="gradientView" destination="umc-Uj-AVs" id="q4m-Ib-c0V"/>
                         <outlet property="hideButton" destination="s0z-cK-ISY" id="PeP-TI-Y2O"/>
                         <outlet property="imageBottomConstraint" destination="Z3A-GV-6Py" id="4dp-wF-Ix2"/>
@@ -75,6 +118,8 @@
                         <outlet property="imageTrailingConstraint" destination="Zxa-bY-zaY" id="gac-QR-lKz"/>
                         <outlet property="imageView" destination="kNJ-67-zFf" id="rTG-bA-Gz6"/>
                         <outlet property="playerView" destination="Jga-0U-qXG" id="nNg-vJ-wZp"/>
+                        <outlet property="saveButton" destination="5q1-cC-MI7" id="QG0-Vq-ETD"/>
+                        <outlet property="shareButton" destination="Gvs-6O-5Fs" id="FNx-Hm-Hav"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="5Ku-db-uak" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
@@ -82,4 +127,13 @@
             <point key="canvasLocation" x="137.68115942028987" y="96.428571428571431"/>
         </scene>
     </scenes>
+    <resources>
+        <image name="ic_conversation_remove" width="27" height="27"/>
+        <image name="ic_forward" width="27" height="27"/>
+        <image name="ic_save" width="27" height="27"/>
+        <image name="ic_share" width="24" height="24"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
 </document>
diff --git a/Ring/Ring/Features/Conversations/Preview/PreviewViewController.swift b/Ring/Ring/Features/Conversations/Preview/PreviewViewController.swift
index 0d55efeb26c1fef200be52c83a195e6bb943fa35..a70802744239ef133f6df2c6a90cd945a7631155 100644
--- a/Ring/Ring/Features/Conversations/Preview/PreviewViewController.swift
+++ b/Ring/Ring/Features/Conversations/Preview/PreviewViewController.swift
@@ -27,6 +27,13 @@ enum PrevewType {
     case image
 }
 
+protocol PreviewViewControllerDelegate: class {
+    func deleteFile()
+    func shareFile()
+    func forwardFile()
+    func saveFile()
+}
+
 class PreviewViewController: UIViewController, StoryboardBased, ViewModelBased {
 // MARK: - outlets
 @IBOutlet weak var playerView: PlayerView!
@@ -38,12 +45,18 @@ class PreviewViewController: UIViewController, StoryboardBased, ViewModelBased {
 @IBOutlet weak var imageBottomConstraint: NSLayoutConstraint!
 @IBOutlet weak var backgroundView: UIView!
 @IBOutlet weak var gradientView: UIView!
+@IBOutlet weak var shareButton: UIButton!
+@IBOutlet weak var deleteButton: UIButton!
+@IBOutlet weak var forwardButton: UIButton!
+@IBOutlet weak var saveButton: UIButton!
+@IBOutlet weak var buttonsContainer: UIStackView!
 
 // MARK: - members
     let disposeBag = DisposeBag()
     var viewModel: PreviewControllerModel!
     var tapGestureRecognizer: UITapGestureRecognizer!
     var type: PrevewType = .player
+    weak var delegate: PreviewViewControllerDelegate?
 
     override func viewDidLoad() {
         super.viewDidLoad()
@@ -67,8 +80,41 @@ class PreviewViewController: UIViewController, StoryboardBased, ViewModelBased {
             .disposed(by: self.disposeBag)
         self.hideButton.centerYAnchor.constraint(equalTo: self.playerView.muteAudio.centerYAnchor, constant: 0).isActive = true
         self.hideButton.setTitle(L10n.Global.close, for: .normal)
+        self.shareButton.isUserInteractionEnabled = self.type == .image
+        self.deleteButton.isUserInteractionEnabled = self.type == .image
+        self.forwardButton.isUserInteractionEnabled = self.type == .image
+        buttonsContainer.isHidden = self.type != .image
         if self.type == .image, let image = self.viewModel.image {
             self.imageView.image = image
+            let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(startZooming(_:)))
+            imageView.isUserInteractionEnabled = true
+            imageView.addGestureRecognizer(pinchGesture)
+            self.shareButton.rx.tap
+                .subscribe(onNext: { [weak self] in
+                    self?.share()
+                })
+                .disposed(by: self.disposeBag)
+            self.deleteButton.rx.tap
+                .subscribe(onNext: { [weak self] in
+                    self?.parent?.inputAccessoryView?.isHidden = false
+                    self?.removeChildController()
+                    self?.delete()
+                })
+                .disposed(by: self.disposeBag)
+            self.forwardButton.rx.tap
+                .subscribe(onNext: { [weak self] in
+                    self?.forward()
+                    self?.parent?.inputAccessoryView?.isHidden = false
+                    self?.removeChildController()
+                })
+                .disposed(by: self.disposeBag)
+            self.saveButton.rx.tap
+                .subscribe(onNext: { [weak self] in
+                    self?.parent?.inputAccessoryView?.isHidden = false
+                    self?.removeChildController()
+                    self?.save()
+                })
+                .disposed(by: self.disposeBag)
             return
         }
         guard let model = self.viewModel.playerViewModel, let playerView = playerView else { return }
@@ -77,6 +123,14 @@ class PreviewViewController: UIViewController, StoryboardBased, ViewModelBased {
         self.view.addGestureRecognizer(tapGestureRecognizer)
     }
 
+    @objc
+     private func startZooming(_ sender: UIPinchGestureRecognizer) {
+       let scaleResult = sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)
+       guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
+       sender.view?.transform = scale
+       sender.scale = 1
+     }
+
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         self.navigationController?.setNavigationBarHidden(true, animated: animated)
@@ -120,4 +174,25 @@ class PreviewViewController: UIViewController, StoryboardBased, ViewModelBased {
                         self.view.layoutIfNeeded()
             }, completion: nil)
     }
+    func share() {
+        if let delegate = self.delegate {
+            delegate.shareFile()
+        }
+    }
+    func delete() {
+        if let delegate = self.delegate {
+            delegate.deleteFile()
+        }
+    }
+    func forward() {
+        if let delegate = self.delegate {
+            delegate.forwardFile()
+        }
+    }
+
+    func save() {
+        if let delegate = self.delegate {
+            delegate.saveFile()
+        }
+    }
 }
diff --git a/Ring/Ring/Protocols/ConversationNavigation.swift b/Ring/Ring/Protocols/ConversationNavigation.swift
index 22c741bb2217810a8d29720d67d752b1457bda85..f01bda3cc6e6cf6f5469a380c029309aafc48f03 100644
--- a/Ring/Ring/Protocols/ConversationNavigation.swift
+++ b/Ring/Ring/Protocols/ConversationNavigation.swift
@@ -36,7 +36,7 @@ enum ConversationState: State {
     case fromCallToConversation(conversation: ConversationViewModel)
     case needAccountMigration(accountId: String)
     case accountModeChanged
-    case openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect)
+    case openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect, delegate: PreviewViewControllerDelegate)
     case replaceCurrentWithConversationFor(participantUri: String)
 }
 
@@ -75,8 +75,8 @@ extension ConversationNavigation where Self: Coordinator, Self: StateableRespons
                     self.migrateAccount(accountId: accountId)
                 case .accountModeChanged:
                     self.accountModeChanged()
-                case .openFullScreenPreview(let parentView, let viewModel, let image, let initialFrame):
-                    self.openFullScreenPreview(parentView: parentView, viewModel: viewModel, image: image, initialFrame: initialFrame)
+                case .openFullScreenPreview(let parentView, let viewModel, let image, let initialFrame, let delegate):
+                    self.openFullScreenPreview(parentView: parentView, viewModel: viewModel, image: image, initialFrame: initialFrame, delegate: delegate)
                 default:
                     break
                 }
@@ -105,9 +105,10 @@ extension ConversationNavigation where Self: Coordinator, Self: StateableRespons
                      withStateable: recordFileViewController.viewModel)
     }
 
-    func openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect) {
+    func openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect, delegate: PreviewViewControllerDelegate) {
         if viewModel == nil && image == nil { return }
         let previewController = PreviewViewController.instantiate(with: self.injectionBag)
+        previewController.delegate = delegate
         if let viewModel = viewModel {
             previewController.viewModel.playerViewModel = viewModel
             previewController.type = .player
diff --git a/Ring/Ring/Resources/Images.xcassets/Contents.json b/Ring/Ring/Resources/Images.xcassets/Contents.json
index 37c3608ab673951e0b0c18f4d6a3051b828206b4..18a5a36fd88f995005adb7fc678cde23abe71fd6 100644
--- a/Ring/Ring/Resources/Images.xcassets/Contents.json
+++ b/Ring/Ring/Resources/Images.xcassets/Contents.json
@@ -1,9 +1,9 @@
 {
   "info" : {
-    "version" : 1,
-    "author" : "xcode"
+    "author" : "xcode",
+    "version" : 1
   },
   "properties" : {
     "compression-type" : "lossy"
   }
-}
\ No newline at end of file
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/Contents.json
index e73088e1e7011de24e2bdb5695d2290d5cb2f5f4..07738c2f43a16583abdfbf46100daeaed6719d5b 100644
--- a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/Contents.json
+++ b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/Contents.json
@@ -1,23 +1,27 @@
 {
   "images" : [
     {
+      "filename" : "trash-can-outline.png",
       "idiom" : "universal",
-      "filename" : "delete-2.png",
       "scale" : "1x"
     },
     {
+      "filename" : "trash-can-outline-2.png",
       "idiom" : "universal",
-      "filename" : "delete.png",
       "scale" : "2x"
     },
     {
+      "filename" : "trash-can-outline-3.png",
       "idiom" : "universal",
-      "filename" : "delete-1.png",
       "scale" : "3x"
     }
   ],
   "info" : {
-    "version" : 1,
-    "author" : "xcode"
+    "author" : "xcode",
+    "version" : 1
+  },
+  "properties" : {
+    "preserves-vector-representation" : true,
+    "template-rendering-intent" : "template"
   }
-}
\ No newline at end of file
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-1.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-1.png
deleted file mode 100644
index 04d7a8edcbfb56087078e6509c0e8f39b3ac2461..0000000000000000000000000000000000000000
Binary files a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-1.png and /dev/null differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-2.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-2.png
deleted file mode 100644
index 8e741fc4248e814b22b74fb58cc2891b3e4ea0da..0000000000000000000000000000000000000000
Binary files a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete-2.png and /dev/null differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete.png
deleted file mode 100644
index d182d87146a01e56fc1aff7eb7ef4676852001e8..0000000000000000000000000000000000000000
Binary files a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/delete.png and /dev/null differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-2.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a3e09cebd4b5665f22a9792bb403e40986e8d56
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-2.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-3.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..4dc5af188f782b8018e9aa8d4da19daf5b200415
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline-3.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline.png b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a02c464c273daa50ac11ff3c51d51ca0d56ccf2
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_conversation_remove.imageset/trash-can-outline.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/Contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..ac290e18f3c1a0e9a0f9814955aa720ed38ec125
--- /dev/null
+++ b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "share-outline.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "share-outline-2.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "share-outline-4.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-2.png b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..de5588ac43f6f007ac0ed86875cf637bfe253a30
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-2.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-4.png b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..618f70b96585daa2a263596b9d262b1a9e049bfc
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline-4.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline.png b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline.png
new file mode 100644
index 0000000000000000000000000000000000000000..7850257c550347ae850dcdd76efd3fc1daac3362
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_forward.imageset/share-outline.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/Contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..35c0d5881c8bea3f6fb72d5081b4196b002aa8c2
--- /dev/null
+++ b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/Contents.json
@@ -0,0 +1,26 @@
+{
+  "images" : [
+    {
+      "filename" : "tray-arrow-down.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "tray-arrow-down-2.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "tray-arrow-down-4.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  },
+  "properties" : {
+    "template-rendering-intent" : "template"
+  }
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-2.png b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..91ede05ff54b0705ab75972dde0002807dd11942
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-2.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-4.png b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..2564dcfee939661f5ab4d6b58bd2473999dc1902
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down-4.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down.png b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down.png
new file mode 100644
index 0000000000000000000000000000000000000000..16f6e969a6fcf77feedeeca48a62a6a1fb52d94b
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_save.imageset/tray-arrow-down.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/Contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..c9e7ccc34f749cf81778cb65455153f269e027cf
--- /dev/null
+++ b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "export-variant-3.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "export-variant-4.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "export-variant.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-3.png b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..16dd4d7800bb414d63df05af1e6dffd5c585273a
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-3.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-4.png b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..74cc4fafcf3c29ab6cc58f20e771aae97309c9bf
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant-4.png differ
diff --git a/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant.png b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant.png
new file mode 100644
index 0000000000000000000000000000000000000000..44ab9a3edc40397e1ac9a818bdb47bb6b1157a99
Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/ic_share.imageset/export-variant.png differ
diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings
index c9d80a5e2ca4fa2a268cd1c77aa6a2d92fb1e7d8..6eaee9da816850a47bf13b81a3b4147bcea81a51 100644
--- a/Ring/Ring/Resources/en.lproj/Localizable.strings
+++ b/Ring/Ring/Resources/en.lproj/Localizable.strings
@@ -26,6 +26,10 @@
 "global.versionName" = "Together";
 "global.close" = "Close";
 "global.share" = "Share";
+"global.forward" = "Forward";
+"global.save" = "Save";
+"global.resend" = "Resend";
+"global.preview" = "Preview";
 
 // Scan
 "scan.badQrCode" = "Bad QR code";
@@ -50,6 +54,7 @@
 "conversation.messagePlaceholder" = "Write message to ";
 "conversation.explanationSendingLocationTo" = "You are currently sharing your location with ";
 "conversation.explanationReceivingLocationFrom" = "You are currently receiving a live location from ";
+"conversation.errorSavingImage" = "Failed to save image to galery";
 
 //Invitations
 "invitations.noInvitations" = "No invitations";