mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
177 lines
6 KiB
Swift
177 lines
6 KiB
Swift
//
|
||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||
//
|
||
|
||
import Foundation
|
||
import SignalServiceKit
|
||
import SignalMessaging
|
||
|
||
@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
|
||
|
||
let messageBody: String
|
||
|
||
var messageTextView: UITextView!
|
||
|
||
// 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
|
||
|
||
self.messageBody = LongTextViewController.displayableText(viewItem: viewItem)
|
||
|
||
super.init(nibName: nil, bundle: nil)
|
||
}
|
||
|
||
private class func displayableText(viewItem: ConversationViewItem) -> String {
|
||
guard viewItem.hasBodyText else {
|
||
return ""
|
||
}
|
||
guard let displayableText = viewItem.displayableBodyText else {
|
||
return ""
|
||
}
|
||
let messageBody = displayableText.fullText
|
||
return messageBody
|
||
}
|
||
|
||
// MARK: View Lifecycle
|
||
|
||
public override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
|
||
self.navigationItem.title = NSLocalizedString("LONG_TEXT_VIEW_TITLE",
|
||
comment: "Title for the 'long text message' view.")
|
||
|
||
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 = Theme.backgroundColor
|
||
|
||
let messageTextView = OWSTextView()
|
||
self.messageTextView = messageTextView
|
||
messageTextView.font = UIFont.ows_dynamicTypeBody
|
||
messageTextView.backgroundColor = Theme.backgroundColor
|
||
messageTextView.isOpaque = true
|
||
messageTextView.isEditable = false
|
||
messageTextView.isSelectable = true
|
||
messageTextView.isScrollEnabled = true
|
||
messageTextView.showsHorizontalScrollIndicator = false
|
||
messageTextView.showsVerticalScrollIndicator = true
|
||
messageTextView.isUserInteractionEnabled = true
|
||
messageTextView.textColor = Theme.primaryColor
|
||
messageTextView.dataDetectorTypes = kOWSAllowedDataDetectorTypes
|
||
messageTextView.text = messageBody
|
||
|
||
// RADAR #18669
|
||
// https://github.com/lionheart/openradar-mirror/issues/18669
|
||
//
|
||
// UITextView’s linkTextAttributes property has type [String : Any]! but should be [NSAttributedStringKey : Any]! in Swift 4.
|
||
let linkTextAttributes: [String: Any] = [
|
||
NSAttributedStringKey.foregroundColor.rawValue: Theme.primaryColor,
|
||
NSAttributedStringKey.underlineColor.rawValue: Theme.primaryColor,
|
||
NSAttributedStringKey.underlineStyle.rawValue: NSUnderlineStyle.styleSingle.rawValue
|
||
]
|
||
messageTextView.linkTextAttributes = linkTextAttributes
|
||
|
||
view.addSubview(messageTextView)
|
||
messageTextView.autoPinEdge(toSuperviewEdge: .top)
|
||
messageTextView.autoPinEdge(toSuperviewMargin: .leading)
|
||
messageTextView.autoPinEdge(toSuperviewMargin: .trailing)
|
||
|
||
let footer = UIToolbar()
|
||
view.addSubview(footer)
|
||
footer.autoPinWidthToSuperview()
|
||
footer.autoPinEdge(.top, to: .bottom, of: messageTextView)
|
||
footer.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
|
||
|
||
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() {
|
||
AttachmentSharing.showShareUI(forText: messageBody)
|
||
}
|
||
}
|