@@ -8,9 +8,7 @@ import Photos
88import UIKit
99import WordPressEditor
1010
11- class EditorDemoController : UIViewController {
12-
13- fileprivate var mediaErrorMode = false
11+ class EditorDemoController : UIViewController {
1412
1513 fileprivate( set) lazy var formatBar : Aztec . FormatBar = {
1614 return self . createToolbar ( )
@@ -27,6 +25,10 @@ class EditorDemoController: UIViewController {
2725 return editorView. htmlTextView
2826 }
2927 }
28+
29+ fileprivate( set) lazy var mediaInsertionHelper : MediaInsertionHelper = {
30+ return MediaInsertionHelper ( textView: self . richTextView, messageAttributes: Constants . mediaMessageAttributes)
31+ } ( )
3032
3133 fileprivate( set) lazy var editorView : Aztec . EditorView = {
3234 let defaultHTMLFont : UIFont
@@ -1108,8 +1110,7 @@ extension EditorDemoController: TextViewAttachmentDelegate {
11081110 return nil
11091111 }
11101112
1111- // TODO: start fake upload process
1112- return saveToDisk ( image: image)
1113+ return mediaInsertionHelper. saveToDisk ( image: image)
11131114 }
11141115
11151116 func textView( _ textView: TextView , deletedAttachment attachment: MediaAttachment ) {
@@ -1148,7 +1149,7 @@ extension EditorDemoController: TextViewAttachmentDelegate {
11481149 // and mark the newly tapped attachment
11491150 if attachment. message == nil {
11501151 let message = NSLocalizedString ( " Options " , comment: " Options to show when tapping on a media object on the post/page editor. " )
1151- attachment. message = NSAttributedString ( string: message, attributes: mediaMessageAttributes)
1152+ attachment. message = NSAttributedString ( string: message, attributes: Constants . mediaMessageAttributes)
11521153 }
11531154 attachment. overlayImage = Gridicon . iconOfType ( . pencil, withSize: CGSize ( width: 32.0 , height: 32.0 ) ) . withRenderingMode ( . alwaysTemplate)
11541155 richTextView. refresh ( attachment)
@@ -1203,13 +1204,13 @@ let info = convertFromUIImagePickerControllerInfoKeyDictionary(info)
12031204 }
12041205
12051206 // Insert Image + Reclaim Focus
1206- insertImage ( image)
1207+ mediaInsertionHelper . insertImage ( image)
12071208
12081209 case typeMovie:
12091210 guard let videoURL = info [ convertFromUIImagePickerControllerInfoKey ( UIImagePickerController . InfoKey. mediaURL) ] as? URL else {
12101211 return
12111212 }
1212- insertVideo ( videoURL)
1213+ mediaInsertionHelper . insertVideo ( videoURL)
12131214 default :
12141215 print ( " Media type not supported: \( mediaType) " )
12151216 }
@@ -1312,97 +1313,10 @@ private extension EditorDemoController {
13121313 task. resume ( )
13131314 }
13141315}
1315- // MARK: - Misc
1316- //
1317- private extension EditorDemoController
1318- {
1319- func saveToDisk( image: UIImage ) -> URL {
1320- let fileName = " \( ProcessInfo . processInfo. globallyUniqueString) _file.jpg "
1321-
1322- guard let data = image. jpegData ( compressionQuality: 0.9 ) else {
1323- fatalError ( " Could not conert image to JPEG. " )
1324- }
1325-
1326- let fileURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) ) . appendingPathComponent ( fileName)
1327-
1328- guard ( try ? data. write ( to: fileURL, options: [ . atomic] ) ) != nil else {
1329- fatalError ( " Could not write the image to disk. " )
1330- }
1331-
1332- return fileURL
1333- }
1334-
1335- func insertImage( _ image: UIImage ) {
1336-
1337- let fileURL = saveToDisk ( image: image)
1338-
1339- let attachment = richTextView. replaceWithImage ( at: richTextView. selectedRange, sourceURL: fileURL, placeHolderImage: image)
1340- attachment. size = . full
1341- attachment. alignment = ImageAttachment . Alignment. none
1342- if let attachmentRange = richTextView. textStorage. ranges ( forAttachment: attachment) . first {
1343- richTextView. setLink ( fileURL, inRange: attachmentRange)
1344- }
1345- let imageID = attachment. identifier
1346- let progress = Progress ( parent: nil , userInfo: [ MediaProgressKey . mediaID: imageID] )
1347- progress. totalUnitCount = 100
1348-
1349- Timer . scheduledTimer ( timeInterval: 0.1 , target: self , selector: #selector( EditorDemoController . timerFireMethod ( _: ) ) , userInfo: progress, repeats: true )
1350- }
1351-
1352- func insertVideo( _ videoURL: URL ) {
1353- let asset = AVURLAsset ( url: videoURL, options: nil )
1354- let imgGenerator = AVAssetImageGenerator ( asset: asset)
1355- imgGenerator. appliesPreferredTrackTransform = true
1356- guard let cgImage = try ? imgGenerator. copyCGImage ( at: CMTimeMake ( value: 0 , timescale: 1 ) , actualTime: nil ) else {
1357- return
1358- }
1359- let posterImage = UIImage ( cgImage: cgImage)
1360- let posterURL = saveToDisk ( image: posterImage)
1361- let attachment = richTextView. replaceWithVideo ( at: richTextView. selectedRange, sourceURL: URL ( string: " placeholder:// " ) !, posterURL: posterURL, placeHolderImage: posterImage)
1362- let mediaID = attachment. identifier
1363- let progress = Progress ( parent: nil , userInfo: [ MediaProgressKey . mediaID: mediaID, MediaProgressKey . videoURL: videoURL] )
1364- progress. totalUnitCount = 100
1365-
1366- Timer . scheduledTimer ( timeInterval: 0.1 , target: self , selector: #selector( EditorDemoController . timerFireMethod ( _: ) ) , userInfo: progress, repeats: true )
1367- }
1368-
1369- @objc func timerFireMethod( _ timer: Timer ) {
1370- guard let progress = timer. userInfo as? Progress ,
1371- let imageId = progress. userInfo [ MediaProgressKey . mediaID] as? String ,
1372- let attachment = richTextView. attachment ( withId: imageId)
1373- else {
1374- timer. invalidate ( )
1375- return
1376- }
1377- progress. completedUnitCount += 1
1378-
1379- attachment. progress = progress. fractionCompleted
1380- if mediaErrorMode && progress. fractionCompleted >= 0.25 {
1381- timer. invalidate ( )
1382- let message = NSAttributedString ( string: " Upload failed! " , attributes: mediaMessageAttributes)
1383- attachment. message = message
1384- attachment. overlayImage = Gridicon . iconOfType ( . refresh)
1385- }
1386- if progress. fractionCompleted >= 1 {
1387- timer. invalidate ( )
1388- attachment. progress = nil
1389- if let videoAttachment = attachment as? VideoAttachment , let videoURL = progress. userInfo [ MediaProgressKey . videoURL] as? URL {
1390- videoAttachment. updateURL ( videoURL)
1391- }
1392- }
1393- richTextView. refresh ( attachment, overlayUpdateOnly: true )
1394- }
1395-
1396- var mediaMessageAttributes : [ NSAttributedString . Key : Any ] {
1397- let paragraphStyle = NSMutableParagraphStyle ( )
1398- paragraphStyle. alignment = . center
1399-
1400- let attributes : [ NSAttributedString . Key : Any ] = [ . font: UIFont . systemFont ( ofSize: 15 , weight: . semibold) ,
1401- . paragraphStyle: paragraphStyle,
1402- . foregroundColor: UIColor . white]
1403- return attributes
1404- }
14051316
1317+ // MARK: - Media Attachment Actions
1318+ //
1319+ extension EditorDemoController {
14061320 func displayActions( forAttachment attachment: MediaAttachment , position: CGPoint ) {
14071321 let mediaID = attachment. identifier
14081322 let title : String = NSLocalizedString ( " Media Options " , comment: " Title for action sheet with media options. " )
@@ -1449,14 +1363,14 @@ private extension EditorDemoController
14491363 }
14501364
14511365 func displayDetailsForAttachment( _ attachment: ImageAttachment , position: CGPoint ) {
1452-
1366+
14531367 let caption = richTextView. caption ( for: attachment)
14541368 let detailsViewController = AttachmentDetailsViewController . controller ( for: attachment, with: caption)
1455-
1369+
14561370 let linkInfo = richTextView. linkInfo ( for: attachment)
14571371 let linkRange = linkInfo? . range
14581372 let linkUpdateRange = linkRange ?? richTextView. textStorage. ranges ( forAttachment: attachment) . first!
1459-
1373+
14601374 if let linkURL = linkInfo? . url {
14611375 detailsViewController. linkURL = linkURL
14621376 }
@@ -1475,33 +1389,32 @@ private extension EditorDemoController
14751389 attachment. size = size
14761390 attachment. updateURL ( srcURL)
14771391 }
1478-
1392+
14791393 if let caption = caption, caption. length > 0 {
14801394 self . richTextView. replaceCaption ( for: attachment, with: caption)
14811395 } else {
14821396 self . richTextView. removeCaption ( for: attachment)
14831397 }
1484-
1398+
14851399 if let newLinkURL = linkURL {
14861400 self . richTextView. setLink ( newLinkURL, inRange: linkUpdateRange)
14871401 } else if linkURL != nil {
14881402 self . richTextView. removeLink ( inRange: linkUpdateRange)
14891403 }
14901404 }
1491-
1405+
14921406 let selectedRange = richTextView. selectedRange
1493-
1494- detailsViewController. onDismiss = { [ unowned self] in
1407+
1408+ detailsViewController. onDismiss = { [ unowned self] in
14951409 self . richTextView. becomeFirstResponder ( )
14961410 self . richTextView. selectedRange = selectedRange
14971411 }
14981412
1499- let navigationController = UINavigationController ( rootViewController: detailsViewController)
1413+ let navigationController = UINavigationController ( rootViewController: detailsViewController)
15001414 present ( navigationController, animated: true , completion: nil )
15011415 }
15021416}
15031417
1504-
15051418extension EditorDemoController {
15061419
15071420 static var tintedMissingImage : UIImage = {
@@ -1522,12 +1435,16 @@ extension EditorDemoController {
15221435 static let lists = [ TextList . Style. unordered, . ordered]
15231436 static let moreAttachmentText = " more "
15241437 static let titleInsets = UIEdgeInsets ( top: 5 , left: 0 , bottom: 5 , right: 0 )
1525- }
1438+ static var mediaMessageAttributes : [ NSAttributedString . Key : Any ] {
1439+ let paragraphStyle = NSMutableParagraphStyle ( )
1440+ paragraphStyle. alignment = . center
15261441
1527- struct MediaProgressKey {
1528- static let mediaID = ProgressUserInfoKey ( " mediaID " )
1529- static let videoURL = ProgressUserInfoKey ( " videoURL " )
1530- }
1442+ let attributes : [ NSAttributedString . Key : Any ] = [ . font: UIFont . systemFont ( ofSize: 15 , weight: . semibold) ,
1443+ . paragraphStyle: paragraphStyle,
1444+ . foregroundColor: UIColor . white]
1445+ return attributes
1446+ }
1447+ }
15311448}
15321449
15331450extension FormattingIdentifier {
0 commit comments