2 // FolioReaderQuoteShare.swift
5 // Created by Heberti Almeida on 8/11/16.
6 // Copyright (c) 2016 Folio Reader. All rights reserved.
11 class FolioReaderQuoteShare: UIViewController {
12 var quoteText: String!
13 var filterImage: UIView!
14 var imageView: UIImageView!
15 var quoteLabel: UILabel!
16 var titleLabel: UILabel!
17 var authorLabel: UILabel!
18 var logoImageView: UIImageView!
19 var collectionView: UICollectionView!
20 let collectionViewLayout = UICollectionViewFlowLayout()
21 let itemSize: CGFloat = 90
22 var dataSource = [QuoteImage]()
23 // let imagePicker = UIImagePickerController()
26 fileprivate var book: FRBook
27 fileprivate var folioReader: FolioReader
28 fileprivate var readerConfig: FolioReaderConfig
32 init(initWithText shareText: String, readerConfig: FolioReaderConfig, folioReader: FolioReader, book: FRBook) {
33 self.folioReader = folioReader
34 self.readerConfig = readerConfig
35 self.quoteText = shareText.stripLineBreaks().stripHtml()
38 super.init(nibName: nil, bundle: Bundle.frameworkBundle())
41 required init?(coder aDecoder: NSCoder) {
42 fatalError("storyboards are incompatible with truth and beauty")
45 override func viewWillAppear(_ animated: Bool) {
46 super.viewWillAppear(animated)
47 setNeedsStatusBarAppearanceUpdate()
50 override func viewDidLoad() {
53 self.setCloseButton(withConfiguration: self.readerConfig)
56 let titleAttrs = [NSAttributedStringKey.foregroundColor: self.readerConfig.tintColor]
57 let share = UIBarButtonItem(title: self.readerConfig.localizedShare, style: .plain, target: self, action: #selector(shareQuote(_:)))
58 share.setTitleTextAttributes(titleAttrs, for: UIControlState())
59 navigationItem.rightBarButtonItem = share
61 let isPad = (UIDevice.current.userInterfaceIdiom == .pad)
63 preferredContentSize = CGSize(width: 400, height: 600)
65 let screenBounds = (isPad == true ? preferredContentSize : UIScreen.main.bounds.size)
67 self.filterImage = UIView(frame: CGRect(x: 0, y: 0, width: screenBounds.width, height: screenBounds.width))
68 self.filterImage.backgroundColor = self.readerConfig.menuSeparatorColor
69 view.addSubview(self.filterImage)
71 imageView = UIImageView(frame: filterImage.bounds)
72 filterImage.addSubview(imageView)
74 quoteLabel = UILabel()
75 quoteLabel.text = quoteText
76 quoteLabel.textAlignment = .center
77 quoteLabel.font = UIFont(name: "Andada-Regular", size: 26)
78 quoteLabel.textColor = UIColor.white
79 quoteLabel.numberOfLines = 0
80 quoteLabel.baselineAdjustment = .alignCenters
81 quoteLabel.translatesAutoresizingMaskIntoConstraints = false
82 quoteLabel.adjustsFontSizeToFitWidth = true
83 quoteLabel.minimumScaleFactor = 0.3
84 quoteLabel.setContentCompressionResistancePriority(UILayoutPriority(100), for: .vertical)
85 filterImage.addSubview(quoteLabel)
90 if let title = self.book.title {
94 if let author = self.book.metadata.creators.first {
95 authorName = author.name
98 titleLabel = UILabel()
99 titleLabel.text = bookTitle
100 titleLabel.font = UIFont(name: "Lato-Bold", size: 15)
101 titleLabel.textAlignment = .center
102 titleLabel.textColor = UIColor.white
103 titleLabel.numberOfLines = 1
104 titleLabel.translatesAutoresizingMaskIntoConstraints = false
105 titleLabel.adjustsFontSizeToFitWidth = true
106 titleLabel.minimumScaleFactor = 0.8
107 titleLabel.setContentCompressionResistancePriority(UILayoutPriority(600), for: .vertical)
108 filterImage.addSubview(titleLabel)
111 let attrs = [NSAttributedStringKey.font: UIFont(name: "Lato-Italic", size: 15)!]
112 let attributedString = NSMutableAttributedString(string:"\(self.readerConfig.localizedShareBy) ", attributes: attrs)
114 let attrs1 = [NSAttributedStringKey.font: UIFont(name: "Lato-Regular", size: 15)!]
115 let boldString = NSMutableAttributedString(string: authorName, attributes:attrs1)
116 attributedString.append(boldString)
118 authorLabel = UILabel()
119 authorLabel.attributedText = attributedString
120 authorLabel.textAlignment = .center
121 authorLabel.textColor = UIColor.white
122 authorLabel.numberOfLines = 1
123 authorLabel.translatesAutoresizingMaskIntoConstraints = false
124 authorLabel.adjustsFontSizeToFitWidth = true
125 authorLabel.minimumScaleFactor = 0.5
126 filterImage.addSubview(authorLabel)
128 let logoImage = self.readerConfig.quoteCustomLogoImage
129 let logoHeight = logoImage?.size.height ?? 0
130 logoImageView = UIImageView(image: logoImage)
131 logoImageView.contentMode = .center
132 logoImageView.translatesAutoresizingMaskIntoConstraints = false
133 filterImage.addSubview(logoImageView)
135 // Configure layout contraints
136 var constraints = [NSLayoutConstraint]()
138 "quoteLabel": self.quoteLabel,
139 "titleLabel": self.titleLabel,
140 "authorLabel": self.authorLabel,
141 "logoImageView": self.logoImageView
144 NSLayoutConstraint.constraints(withVisualFormat: "V:|-40-[quoteLabel]-20-[titleLabel]", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
145 NSLayoutConstraint.constraints(withVisualFormat: "V:[titleLabel]-0-[authorLabel]", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
146 NSLayoutConstraint.constraints(withVisualFormat: "V:[authorLabel]-25-[logoImageView(\(Int(logoHeight)))]-18-|", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
148 NSLayoutConstraint.constraints(withVisualFormat: "H:|-15-[quoteLabel]-15-|", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
149 NSLayoutConstraint.constraints(withVisualFormat: "H:|-15-[titleLabel]-15-|", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
150 NSLayoutConstraint.constraints(withVisualFormat: "H:|-15-[authorLabel]-15-|", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
151 NSLayoutConstraint.constraints(withVisualFormat: "H:|-15-[logoImageView]-15-|", options: [], metrics: nil, views: views).forEach { constraints.append($0) }
153 filterImage.addConstraints(constraints)
156 collectionViewLayout.sectionInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
157 collectionViewLayout.minimumLineSpacing = 15
158 collectionViewLayout.minimumInteritemSpacing = 0
159 collectionViewLayout.scrollDirection = .horizontal
161 let background = self.folioReader.isNight(self.readerConfig.nightModeBackground, UIColor.white)
162 view.backgroundColor = background
165 let collectionFrame = CGRect(x: 0, y: filterImage.frame.height+15, width: screenBounds.width, height: itemSize)
166 collectionView = UICollectionView(frame: collectionFrame, collectionViewLayout: collectionViewLayout)
167 collectionView.delegate = self
168 collectionView.dataSource = self
169 collectionView.showsHorizontalScrollIndicator = false
170 collectionView.backgroundColor = background
171 collectionView.decelerationRate = UIScrollViewDecelerationRateFast
172 view.addSubview(collectionView)
174 if (UIDevice.current.userInterfaceIdiom == .phone) {
175 collectionView.autoresizingMask = [.flexibleWidth]
178 // Register cell classes
179 collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: kReuseCellIdentifier)
182 dataSource = self.readerConfig.quoteCustomBackgrounds
183 if (self.readerConfig.quotePreserveDefaultBackgrounds == true) {
184 createDefaultImages()
188 // imagePicker.delegate = self
194 func configureNavBar() {
195 let navBackground = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white)
196 let tintColor = self.readerConfig.tintColor
197 let navText = self.folioReader.isNight(UIColor.white, UIColor.black)
198 let font = UIFont(name: "Avenir-Light", size: 17)!
199 setTranslucentNavigation(false, color: navBackground, tintColor: tintColor, titleColor: navText, andFont: font)
202 func createDefaultImages() {
203 let color1 = QuoteImage(withColor: UIColor(rgba: "#FA7B67"))
204 let color2 = QuoteImage(withColor: UIColor(rgba: "#78CAB6"))
205 let color3 = QuoteImage(withColor: UIColor(rgba: "#71B630"))
206 let color4 = QuoteImage(withColor: UIColor(rgba: "#4D5B49"))
207 let color5 = QuoteImage(withColor: UIColor(rgba: "#959D92"), textColor: UIColor(rgba: "#4D5B49"))
209 var gradient = CAGradientLayer()
210 gradient.colors = [UIColor(rgba: "#2989C9").cgColor, UIColor(rgba: "#21B8C2").cgColor]
211 gradient.startPoint = CGPoint(x: 0, y: 1)
212 gradient.endPoint = CGPoint(x: 1, y: 0)
213 let gradient1 = QuoteImage(withGradient: gradient)
215 gradient = CAGradientLayer()
216 gradient.colors = [UIColor(rgba: "#FAD961").cgColor, UIColor(rgba: "#F76B1C").cgColor]
217 let gradient2 = QuoteImage(withGradient: gradient)
219 gradient = CAGradientLayer()
220 gradient.colors = [UIColor(rgba: "#B4EC51").cgColor, UIColor(rgba: "#429321").cgColor]
221 let gradient3 = QuoteImage(withGradient: gradient)
223 dataSource.append(contentsOf: [color1, color2, color3, color4, color5, gradient1, gradient2, gradient3])
226 func selectIndex(_ index: Int) {
227 let quoteImage = dataSource[index]
230 filterImage.backgroundColor = quoteImage.backgroundColor
231 imageView.alpha = quoteImage.alpha
233 UIView.transition(with: filterImage, duration: 0.4, options: .transitionCrossDissolve, animations: {
234 self.imageView.image = quoteImage.image
235 self.quoteLabel.textColor = quoteImage.textColor
236 self.titleLabel.textColor = quoteImage.textColor
237 self.authorLabel.textColor = quoteImage.textColor
238 self.logoImageView.image = self.logoImageView.image?.imageTintColor(quoteImage.textColor)
242 let prevSelectedIndex = selectedIndex
245 guard prevSelectedIndex != selectedIndex else { return }
247 collectionView.performBatchUpdates({
248 self.collectionView.reloadItems(at: [
249 IndexPath(item: self.selectedIndex, section: 0),
250 IndexPath(item: prevSelectedIndex, section: 0)
257 @objc func shareQuote(_ sender: UIBarButtonItem) {
258 var subject = self.readerConfig.localizedShareHighlightSubject
262 var shareItems = [AnyObject]()
265 if let title = self.book.title {
267 subject += " “\(title)”"
271 if let author = self.book.metadata.creators.first {
272 authorName = author.name
275 text = "\(bookTitle) \n\(self.readerConfig.localizedShareBy) \(authorName)"
277 let imageQuote = UIImage.imageWithView(filterImage)
278 shareItems.append(imageQuote)
280 if let bookShareLink = self.readerConfig.localizedShareWebLink {
281 text += "\n\(bookShareLink.absoluteString)"
284 let act = FolioReaderSharingProvider(subject: subject, text: text)
285 shareItems.insert(act, at: 0)
287 let activityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
288 activityViewController.excludedActivityTypes = [UIActivityType.print, UIActivityType.postToVimeo]
291 if let actv = activityViewController.popoverPresentationController {
292 actv.barButtonItem = sender
295 present(activityViewController, animated: true, completion: nil)
300 override var preferredStatusBarStyle : UIStatusBarStyle {
301 return self.folioReader.isNight(.lightContent, .default)
304 override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
308 override var shouldAutorotate : Bool {
313 // MARK: UICollectionViewDataSource
315 extension FolioReaderQuoteShare: UICollectionViewDataSource {
316 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
317 return dataSource.count + 1
320 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
321 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kReuseCellIdentifier, for: indexPath)
322 let imageView: UIImageView!
325 cell.backgroundColor = UIColor.clear
326 cell.contentView.backgroundColor = UIColor.clear
327 cell.contentView.layer.borderWidth = 1
329 if let view = cell.contentView.viewWithTag(tag) as? UIImageView {
332 imageView = UIImageView(frame: cell.bounds)
334 cell.contentView.addSubview(imageView)
338 guard ((indexPath as NSIndexPath).row > 0) else {
341 let normalColor = UIColor(white: 0.5, alpha: 0.7)
342 let camera = UIImage(readerImageNamed: "icon-camera")
343 let dash = UIImage(readerImageNamed: "border-dashed-pattern")
344 let cameraNormal = camera?.imageTintColor(normalColor)
346 imageView.contentMode = .center
347 imageView.image = cameraNormal
348 if let dashNormal = dash?.imageTintColor(normalColor) {
349 cell.contentView.layer.borderColor = UIColor(patternImage: dashNormal).cgColor
354 if (selectedIndex == (indexPath as NSIndexPath).row) {
355 cell.contentView.layer.borderColor = self.readerConfig.tintColor.cgColor
356 cell.contentView.layer.borderWidth = 3
358 cell.contentView.layer.borderColor = UIColor(white: 0.5, alpha: 0.2).cgColor
361 let quoteImage = dataSource[(indexPath as NSIndexPath).row-1]
362 imageView.image = quoteImage.image
363 imageView.alpha = quoteImage.alpha
364 imageView.contentMode = .scaleAspectFit
365 cell.contentView.backgroundColor = quoteImage.backgroundColor
369 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
370 return CGSize(width: itemSize, height: itemSize)
374 // MARK: UICollectionViewDelegate
376 extension FolioReaderQuoteShare: UICollectionViewDelegate {
377 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
379 guard (indexPath as NSIndexPath).row > 0 else {
380 let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
382 let takePhoto = UIAlertAction(title: self.readerConfig.localizedTakePhoto, style: .default, handler: { (action) -> Void in
383 // self.imagePicker.sourceType = .camera
384 // self.imagePicker.allowsEditing = true
385 // self.present(self.imagePicker, animated: true, completion: nil)
388 let existingPhoto = UIAlertAction(title: self.readerConfig.localizedChooseExisting, style: .default) { (action) -> Void in
389 // self.imagePicker.sourceType = .photoLibrary
390 // self.imagePicker.allowsEditing = true
391 // self.present(self.imagePicker, animated: true, completion: nil)
394 let cancel = UIAlertAction(title: self.readerConfig.localizedCancel, style: .cancel, handler: nil)
396 alertController.addAction(takePhoto)
397 alertController.addAction(existingPhoto)
398 alertController.addAction(cancel)
400 present(alertController, animated: true, completion: nil)
404 selectIndex((indexPath as NSIndexPath).row-1)
408 // MARK: ImagePicker delegate
410 //extension FolioReaderQuoteShare: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
411 // func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
412 // if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
414 // let quoteImage = QuoteImage(withImage: image, alpha: 0.6, backgroundColor: UIColor.black)
416 // collectionView.performBatchUpdates({
417 // self.dataSource.insert(quoteImage, at: 0)
418 // self.collectionView.insertItems(at: [IndexPath(item: 1, section: 0)])
419 // self.collectionView.reloadItems(at: [IndexPath(item: self.selectedIndex, section: 0)])
420 // }, completion: { (finished) in
421 // self.selectIndex(0)
425 // self.dismiss(animated: true, completion: nil)