mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			178 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			178 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Swift
		
	
//
 | 
						|
//  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
import Foundation
 | 
						|
import SignalUtilitiesKit
 | 
						|
 | 
						|
@objc
 | 
						|
public protocol LongTextViewDelegate {
 | 
						|
    @objc
 | 
						|
    func longTextViewMessageWasDeleted(_ longTextViewController: LongTextViewController)
 | 
						|
}
 | 
						|
 | 
						|
@objc
 | 
						|
public class LongTextViewController: OWSViewController {
 | 
						|
 | 
						|
    // MARK: - Dependencies
 | 
						|
 | 
						|
    var uiDatabaseConnection: YapDatabaseConnection {
 | 
						|
        return OWSPrimaryStorage.shared().uiDatabaseConnection
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: - Properties
 | 
						|
 | 
						|
    @objc
 | 
						|
    weak var delegate: LongTextViewDelegate?
 | 
						|
 | 
						|
    let viewItem: ConversationViewItem
 | 
						|
 | 
						|
    var messageTextView: UITextView!
 | 
						|
 | 
						|
    var displayableText: DisplayableText? {
 | 
						|
        return viewItem.displayableBodyText
 | 
						|
    }
 | 
						|
 | 
						|
    var fullText: String {
 | 
						|
        return displayableText?.fullText ?? ""
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: Initializers
 | 
						|
 | 
						|
    @available(*, unavailable, message:"use other constructor instead.")
 | 
						|
    public required init?(coder aDecoder: NSCoder) {
 | 
						|
        notImplemented()
 | 
						|
    }
 | 
						|
 | 
						|
    @objc
 | 
						|
    public required init(viewItem: ConversationViewItem) {
 | 
						|
        self.viewItem = viewItem
 | 
						|
        super.init(nibName: nil, bundle: nil)
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: View Lifecycle
 | 
						|
 | 
						|
    public override func viewDidLoad() {
 | 
						|
        super.viewDidLoad()
 | 
						|
 | 
						|
        ViewControllerUtilities.setUpDefaultSessionStyle(for: self, title: NSLocalizedString("LONG_TEXT_VIEW_TITLE", comment: ""), hasCustomBackButton: false)
 | 
						|
        
 | 
						|
        createViews()
 | 
						|
 | 
						|
        self.messageTextView.contentOffset = CGPoint(x: 0, y: self.messageTextView.contentInset.top)
 | 
						|
 | 
						|
        NotificationCenter.default.addObserver(self,
 | 
						|
                                               selector: #selector(uiDatabaseDidUpdate),
 | 
						|
                                               name: .OWSUIDatabaseConnectionDidUpdate,
 | 
						|
                                               object: OWSPrimaryStorage.shared().dbNotificationObject)
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: - DB
 | 
						|
 | 
						|
    @objc internal func uiDatabaseDidUpdate(notification: NSNotification) {
 | 
						|
        AssertIsOnMainThread()
 | 
						|
 | 
						|
        guard let notifications = notification.userInfo?[OWSUIDatabaseConnectionNotificationsKey] as? [Notification] else {
 | 
						|
            owsFailDebug("notifications was unexpectedly nil")
 | 
						|
            return
 | 
						|
        }
 | 
						|
 | 
						|
        guard let uniqueId = self.viewItem.interaction.uniqueId else {
 | 
						|
            Logger.error("Message is missing uniqueId.")
 | 
						|
            return
 | 
						|
        }
 | 
						|
 | 
						|
        guard self.uiDatabaseConnection.hasChange(forKey: uniqueId,
 | 
						|
                                                  inCollection: TSInteraction.collection(),
 | 
						|
                                                  in: notifications) else {
 | 
						|
                                                    Logger.debug("No relevant changes.")
 | 
						|
                                                    return
 | 
						|
        }
 | 
						|
 | 
						|
        do {
 | 
						|
            try uiDatabaseConnection.read { transaction in
 | 
						|
                guard TSInteraction.fetch(uniqueId: uniqueId, transaction: transaction) != nil else {
 | 
						|
                    Logger.error("Message was deleted")
 | 
						|
                    throw LongTextViewError.messageWasDeleted
 | 
						|
                }
 | 
						|
            }
 | 
						|
        } catch LongTextViewError.messageWasDeleted {
 | 
						|
            DispatchQueue.main.async {
 | 
						|
                self.delegate?.longTextViewMessageWasDeleted(self)
 | 
						|
            }
 | 
						|
        } catch {
 | 
						|
            owsFailDebug("unexpected error: \(error)")
 | 
						|
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    enum LongTextViewError: Error {
 | 
						|
        case messageWasDeleted
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: - Create Views
 | 
						|
 | 
						|
    private func createViews() {
 | 
						|
        view.backgroundColor = Colors.navigationBarBackground
 | 
						|
 | 
						|
        let messageTextView = OWSTextView()
 | 
						|
        self.messageTextView = messageTextView
 | 
						|
        messageTextView.font = .systemFont(ofSize: Values.smallFontSize)
 | 
						|
        messageTextView.backgroundColor = .clear
 | 
						|
        messageTextView.isOpaque = true
 | 
						|
        messageTextView.isEditable = false
 | 
						|
        messageTextView.isSelectable = true
 | 
						|
        messageTextView.isScrollEnabled = true
 | 
						|
        messageTextView.showsHorizontalScrollIndicator = false
 | 
						|
        messageTextView.showsVerticalScrollIndicator = true
 | 
						|
        messageTextView.isUserInteractionEnabled = true
 | 
						|
        messageTextView.textColor = Colors.text
 | 
						|
        messageTextView.contentInset = UIEdgeInsets(top: Values.mediumSpacing, leading: 0, bottom: 0, trailing: 0)
 | 
						|
        if let displayableText = displayableText {
 | 
						|
            messageTextView.text = fullText
 | 
						|
            messageTextView.ensureShouldLinkifyText(displayableText.shouldAllowLinkification)
 | 
						|
        } else {
 | 
						|
            owsFailDebug("displayableText was unexpectedly nil")
 | 
						|
            messageTextView.text = ""
 | 
						|
        }
 | 
						|
 | 
						|
        let linkTextAttributes: [NSAttributedString.Key: Any] = [
 | 
						|
            NSAttributedString.Key.foregroundColor: Colors.text,
 | 
						|
            NSAttributedString.Key.underlineColor: Colors.text,
 | 
						|
            NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
 | 
						|
        ]
 | 
						|
        messageTextView.linkTextAttributes = linkTextAttributes
 | 
						|
 | 
						|
        view.addSubview(messageTextView)
 | 
						|
        messageTextView.autoPinEdge(toSuperviewEdge: .top)
 | 
						|
        messageTextView.autoPinEdge(toSuperviewEdge: .leading)
 | 
						|
        messageTextView.autoPinEdge(toSuperviewEdge: .trailing)
 | 
						|
        messageTextView.textContainerInset = UIEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)
 | 
						|
 | 
						|
        let footer = UIToolbar()
 | 
						|
        view.addSubview(footer)
 | 
						|
        footer.autoPinWidthToSuperview()
 | 
						|
        footer.autoPinEdge(.top, to: .bottom, of: messageTextView)
 | 
						|
        footer.autoPinEdge(toSuperviewSafeArea: .bottom)
 | 
						|
 | 
						|
        footer.items = [
 | 
						|
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
 | 
						|
            UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonPressed)),
 | 
						|
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
 | 
						|
        ]
 | 
						|
    }
 | 
						|
 | 
						|
    // MARK: - Actions
 | 
						|
 | 
						|
    @objc func shareButtonPressed() {
 | 
						|
        let shareVC = UIActivityViewController(activityItems: [ fullText ], applicationActivities: nil)
 | 
						|
        if UIDevice.current.isIPad {
 | 
						|
            shareVC.excludedActivityTypes = []
 | 
						|
            shareVC.popoverPresentationController?.permittedArrowDirections = []
 | 
						|
            shareVC.popoverPresentationController?.sourceView = self.view
 | 
						|
            shareVC.popoverPresentationController?.sourceRect = self.view.bounds
 | 
						|
        }
 | 
						|
        self.present(shareVC, animated: true, completion: nil)
 | 
						|
    }
 | 
						|
}
 |