@ -4,6 +4,12 @@
import Foundation
@objc
enum MessageMetadataViewMode : UInt {
case focusOnMessage
case focusOnMetadata
}
class MessageMetadataViewController : OWSViewController {
static let TAG = " [MessageMetadataViewController] "
@ -18,6 +24,8 @@ class MessageMetadataViewController: OWSViewController {
let bubbleFactory = OWSMessagesBubbleImageFactory ( )
var bubbleView : UIView ?
let mode : MessageMetadataViewMode
let viewItem : ConversationViewItem
var message : TSMessage
var mediaMessageView : MediaMessageView ?
@ -32,18 +40,16 @@ class MessageMetadataViewController: OWSViewController {
// MARK: I n i t i a l i z e r s
@ available ( * , unavailable , message : " use message: constructor instead." )
@ available ( * , unavailable , message : " use other constructor instead." )
required init ? ( coder aDecoder : NSCoder ) {
self . contactsManager = Environment . getCurrent ( ) . contactsManager
self . message = TSMessage ( )
self . databaseConnection = TSStorageManager . shared ( ) . newDatabaseConnection ( ) !
super . init ( coder : aDecoder )
owsFail ( " \( self . TAG ) invalid constructor " )
fatalError ( " \( #function ) is unimplemented. " )
}
required init ( message: TSMessag e) {
required init ( viewItem : ConversationViewItem , message : TSMessage , mode : MessageMetadataViewMode ) {
self . contactsManager = Environment . getCurrent ( ) . contactsManager
self . viewItem = viewItem
self . message = message
self . mode = mode
self . databaseConnection = TSStorageManager . shared ( ) . newDatabaseConnection ( ) !
super . init ( nibName : nil , bundle : nil )
}
@ -62,12 +68,15 @@ class MessageMetadataViewController: OWSViewController {
createViews ( )
self . view . layoutIfNeeded ( )
if let bubbleView = self . bubbleView {
let showAtLeast : CGFloat = 50
let middleCenter = CGPoint ( x : bubbleView . frame . origin . x + bubbleView . frame . width / 2 ,
y : bubbleView . frame . origin . y + bubbleView . frame . height - showAtLeast )
let offset = bubbleView . superview ! . convert ( middleCenter , to : scrollView )
self . scrollView ! . setContentOffset ( offset , animated : false )
if mode = = . focusOnMetadata {
if let bubbleView = self . bubbleView {
let showAtLeast : CGFloat = 50
let middleCenter = CGPoint ( x : bubbleView . frame . origin . x + bubbleView . frame . width / 2 ,
y : bubbleView . frame . origin . y + bubbleView . frame . height - showAtLeast )
let offset = bubbleView . superview ! . convert ( middleCenter , to : scrollView )
self . scrollView ! . setContentOffset ( offset , animated : false )
}
}
NotificationCenter . default . addObserver ( self ,
@ -267,76 +276,79 @@ class MessageMetadataViewController: OWSViewController {
}
}
private func displayableTextIfText ( ) -> String ? {
let messageCellType = viewItem . messageCellType ( )
guard messageCellType = = . textMessage ||
messageCellType = = . oversizeTextMessage else {
return nil
}
guard let displayableText = viewItem . displayableText ( ) else {
return nil
}
let messageBody = displayableText . fullText
guard messageBody . characters . count > 0 else {
return nil
}
return messageBody
}
private func contentRows ( ) -> [ UIView ] {
var rows = [ UIView ] ( )
if message . attachmentIds . count > 0 {
if let messageBody = displayableTextIfText ( ) {
self . messageBody = messageBody
let isIncoming = self . message as ? TSIncomingMessage != nil
// U I T e x t V i e w c a n ' t r e n d e r e x t r e m e l y l o n g t e x t d u e t o c o n s t r a i n t s
// o n t h e s i z e o f i t s b a c k i n g b u f f e r , e s p e c i a l l y w h e n w e ' r e
// e m b e d d i n g i t " f u l l - s i z e ' w i t h i n a U I S c r o l l V i e w a s w e d o i n t h i s v i e w .
//
// TODO: W e c o u l d u s e C o r e T e x t i n s t e a d , o r w e c o u l d d y n a m i c a l l y
// m a n i p u l a t e t h e s i z e / p o s i t i o n o f o u r U I T e x t V i e w t o
// r e f l e c t s c r o l l s t a t e .
let bodyLabel = UITextView ( )
bodyLabel . font = UIFont . ows_dynamicTypeBody ( )
bodyLabel . backgroundColor = UIColor . clear
bodyLabel . isOpaque = false
bodyLabel . isEditable = false
bodyLabel . isSelectable = true
bodyLabel . textContainerInset = UIEdgeInsets . zero
bodyLabel . contentInset = UIEdgeInsets . zero
bodyLabel . isScrollEnabled = false
bodyLabel . textColor = isIncoming ? UIColor . black : UIColor . white
bodyLabel . text = messageBody
let bubbleImageData = isIncoming ? bubbleFactory . incoming : bubbleFactory . outgoing
let leadingMargin : CGFloat = isIncoming ? 15 : 10
let trailingMargin : CGFloat = isIncoming ? 10 : 15
let bubbleView = UIImageView ( image : bubbleImageData . messageBubbleImage )
self . bubbleView = bubbleView
bubbleView . layer . cornerRadius = 10
bubbleView . addSubview ( bodyLabel )
bodyLabel . autoPinEdge ( toSuperviewEdge : . leading , withInset : leadingMargin )
bodyLabel . autoPinEdge ( toSuperviewEdge : . trailing , withInset : trailingMargin )
bodyLabel . autoPinHeightToSuperview ( withMargin : 10 )
let row = UIView ( )
row . addSubview ( bubbleView )
bubbleView . autoPinHeightToSuperview ( )
bubbleView . autoPinLeadingToSuperview ( withMargin : 10 )
bubbleView . autoPinTrailingToSuperview ( withMargin : 10 )
rows . append ( row )
} else if message . attachmentIds . count > 0 {
rows += addAttachmentRows ( )
} else if let messageBody = message . body {
// TODO: W e s h o u l d a l s o d i s p l a y " o v e r s i z e t e x t m e s s a g e s " i n a
// s i m i l a r w a y .
if messageBody . characters . count > 0 {
self . messageBody = messageBody
let isIncoming = self . message as ? TSIncomingMessage != nil
let bodyLabel = UILabel ( )
bodyLabel . textColor = isIncoming ? UIColor . black : UIColor . white
bodyLabel . font = UIFont . ows_regularFont ( withSize : 16 )
bodyLabel . text = messageBody
bodyLabel . numberOfLines = 0
bodyLabel . lineBreakMode = . byWordWrapping
let bubbleImageData = isIncoming ? bubbleFactory . incoming : bubbleFactory . outgoing
let leadingMargin : CGFloat = isIncoming ? 15 : 10
let trailingMargin : CGFloat = isIncoming ? 10 : 15
let bubbleView = UIImageView ( image : bubbleImageData . messageBubbleImage )
self . bubbleView = bubbleView
bubbleView . layer . cornerRadius = 10
bubbleView . addSubview ( bodyLabel )
bodyLabel . autoPinEdge ( toSuperviewEdge : . leading , withInset : leadingMargin )
bodyLabel . autoPinEdge ( toSuperviewEdge : . trailing , withInset : trailingMargin )
bodyLabel . autoPinHeightToSuperview ( withMargin : 10 )
// T r y t o h u g c o n t e n t b o t h h o r i z o n t a l l y a n d v e r t i c a l l y , b u t * p r e f e r * w i d e a n d s h o r t , t o n a r r o w a n d t a l l .
// W h i l e n e v e r e x c e e d i n g m a x w i d t h , a n d n e v e r c r o p p i n g c o n t e n t .
bodyLabel . setContentHuggingPriority ( UILayoutPriorityDefaultLow , for : . horizontal )
bodyLabel . setContentHuggingPriority ( UILayoutPriorityDefaultHigh , for : . vertical )
bodyLabel . setContentCompressionResistancePriority ( UILayoutPriorityRequired , for : . vertical )
bodyLabel . autoSetDimension ( . width , toSize : ScaleFromIPhone5 ( 210 ) , relation : . lessThanOrEqual )
let bubbleSpacer = UIView ( )
let row = UIView ( )
row . addSubview ( bubbleView )
row . addSubview ( bubbleSpacer )
bubbleView . autoPinHeightToSuperview ( )
bubbleSpacer . autoPinHeightToSuperview ( )
bubbleSpacer . setContentHuggingLow ( )
if isIncoming {
bubbleView . autoPinLeadingToSuperview ( withMargin : 10 )
bubbleSpacer . autoPinLeading ( toTrailingOf : bubbleView )
bubbleSpacer . autoPinTrailingToSuperview ( withMargin : 10 )
} else {
bubbleSpacer . autoPinLeadingToSuperview ( withMargin : 10 )
bubbleView . autoPinLeading ( toTrailingOf : bubbleSpacer )
bubbleView . autoPinTrailingToSuperview ( withMargin : 10 )
}
rows . append ( row )
} else {
// N e i t h e r a t t a c h m e n t n o r b o d y .
owsFail ( " \( self . TAG ) Message has neither attachment nor body. " )
rows . append ( valueRow ( name : NSLocalizedString ( " MESSAGE_METADATA_VIEW_NO_ATTACHMENT_OR_BODY " ,
comment : " Label for messages without a body or attachment in the 'message metadata' view. " ) ,
value : " " ) )
}
} else {
// N e i t h e r a t t a c h m e n t n o r b o d y .
owsFail ( " \( self . TAG ) Message has neither attachment nor body. " )
rows . append ( valueRow ( name : NSLocalizedString ( " MESSAGE_METADATA_VIEW_NO_ATTACHMENT_OR_BODY " ,
comment : " Label for messages without a body or attachment in the 'message metadata' view. " ) ,
value : " " ) )
}
let spacer = UIView ( )