diff --git a/elpha-ios.xcodeproj/project.pbxproj b/elpha-ios.xcodeproj/project.pbxproj index 8676c8d..ec60048 100644 --- a/elpha-ios.xcodeproj/project.pbxproj +++ b/elpha-ios.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ 15960E84213774FC00C38CE9 /* InstancesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */; }; 15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1517EA842159D72200DE80D6 /* AlamofireImage.framework */; }; 15A79B43215EB959007A326E /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A79B42215EB959007A326E /* CoreDataManager.swift */; }; + 15B127922192467F00F4EF1D /* String+HtmlAttributed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15B127912192467F00F4EF1D /* String+HtmlAttributed.swift */; }; + 15B127A32192486200F4EF1D /* UIColor+HexString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15B127A22192486200F4EF1D /* UIColor+HexString.swift */; }; 15BB72AB2171A8D4002F1FA4 /* TimelinesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BB72AA2171A8D4002F1FA4 /* TimelinesTableViewCell.swift */; }; 15C91A02216AB2D600D97DC3 /* AlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 15C91A01216AB2D600D97DC3 /* AlertView.xib */; }; 15C91A04216AB32500D97DC3 /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15C91A03216AB32500D97DC3 /* AlertView.swift */; }; @@ -230,6 +232,8 @@ 15960E812136668500C38CE9 /* TimelinesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesNavigationController.swift; sourceTree = ""; }; 15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesTableViewController.swift; sourceTree = ""; }; 15A79B42215EB959007A326E /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = ""; }; + 15B127912192467F00F4EF1D /* String+HtmlAttributed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+HtmlAttributed.swift"; sourceTree = ""; }; + 15B127A22192486200F4EF1D /* UIColor+HexString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+HexString.swift"; sourceTree = ""; }; 15BB72AA2171A8D4002F1FA4 /* TimelinesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesTableViewCell.swift; sourceTree = ""; }; 15C91A01216AB2D600D97DC3 /* AlertView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AlertView.xib; sourceTree = ""; }; 15C91A03216AB32500D97DC3 /* AlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertView.swift; sourceTree = ""; }; @@ -315,6 +319,8 @@ isa = PBXGroup; children = ( 159026CF2163069600D362DD /* Date+TimeAgo.swift */, + 15B127912192467F00F4EF1D /* String+HtmlAttributed.swift */, + 15B127A22192486200F4EF1D /* UIColor+HexString.swift */, ); name = Extensions; sourceTree = ""; @@ -626,10 +632,12 @@ 15F998352162C0E8009E58DA /* MastodonDataManager.swift in Sources */, 15960E7A2132387A00C38CE9 /* MainTabBarController.swift in Sources */, 15960E7C213272CD00C38CE9 /* AuthenticationManager.swift in Sources */, + 15B127922192467F00F4EF1D /* String+HtmlAttributed.swift in Sources */, 15960E7E21329FED00C38CE9 /* AuthenticateViewController.swift in Sources */, 15960E5B213145E100C38CE9 /* AppDelegate.swift in Sources */, 15131EF2216D8D570092B252 /* StatusView.swift in Sources */, 152734D22186DC74003DB3C8 /* TimelinesViewController.swift in Sources */, + 15B127A32192486200F4EF1D /* UIColor+HexString.swift in Sources */, 156FF07221779C650074D9CA /* InstanceRequest.swift in Sources */, 15960E7721322C6F00C38CE9 /* Configuration.swift in Sources */, 156FF07021779C570074D9CA /* MastodonAPI.swift in Sources */, diff --git a/elpha-ios/AccountTableViewController.swift b/elpha-ios/AccountTableViewController.swift index fd8cb18..b04790e 100644 --- a/elpha-ios/AccountTableViewController.swift +++ b/elpha-ios/AccountTableViewController.swift @@ -77,18 +77,7 @@ class AccountTableViewController: UITableViewController { usernameLabel.text = account.acct if let note = account.note { - do { - let styledContent = " \(note)" - let attributedText = try NSAttributedString( - data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!, - options: [.documentType: NSAttributedString.DocumentType.html], - documentAttributes: nil - ) - - contentLabel.attributedText = attributedText - } catch { - print("\(error)") - } + contentLabel.attributedText = note.htmlAttributed(size: 15, centered: true) } statusesLabel.text = NumberFormatter.localizedString(from: NSNumber(value: account.statusesCount), number: .decimal) diff --git a/elpha-ios/AlertView.xib b/elpha-ios/AlertView.xib index 5feb6f5..4b03110 100644 --- a/elpha-ios/AlertView.xib +++ b/elpha-ios/AlertView.xib @@ -35,6 +35,7 @@ + diff --git a/elpha-ios/Base.lproj/Main.storyboard b/elpha-ios/Base.lproj/Main.storyboard index 8e6c58f..b11de00 100644 --- a/elpha-ios/Base.lproj/Main.storyboard +++ b/elpha-ios/Base.lproj/Main.storyboard @@ -240,15 +240,7 @@ - - - - - - - - - + diff --git a/elpha-ios/StatusTableViewController.swift b/elpha-ios/StatusTableViewController.swift index 2edbd68..b86c035 100644 --- a/elpha-ios/StatusTableViewController.swift +++ b/elpha-ios/StatusTableViewController.swift @@ -38,6 +38,7 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + loadStatuses() fetchStatuses { error in if error != nil { @@ -153,7 +154,6 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg self.loading = false self.loadStatuses() - self.tableView.reloadData() completion(nil) } @@ -191,6 +191,8 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg ancestors.reverse() descendants.reverse() + + self.tableView.reloadData() } catch { print("\(error)") } diff --git a/elpha-ios/StatusView.swift b/elpha-ios/StatusView.swift index 8bab6a1..d1f92fa 100644 --- a/elpha-ios/StatusView.swift +++ b/elpha-ios/StatusView.swift @@ -41,7 +41,6 @@ class StatusView: UIView { @IBOutlet var avatarImageView: UIImageView! @IBOutlet var displayNameLabel: UILabel! @IBOutlet var usernameLabel: UILabel! - @IBOutlet var contentLabel: UILabel! @IBOutlet var timestampLabel: UILabel! @IBOutlet var repliesImageView: UIImageView! @IBOutlet var repliesLabel: UILabel! @@ -57,6 +56,7 @@ class StatusView: UIView { @IBOutlet var pinImageView: UIImageView! @IBOutlet var topLoadMoreView: UIView! @IBOutlet var bottomLoadMoreView: UIView! + @IBOutlet var contentTextView: UITextView! var status: StatusMO? = nil var delegate: StatusViewDelegate? = nil @@ -213,10 +213,8 @@ class StatusView: UIView { public func update(withStatus status: StatusMO) { self.status = status - topDividerView.isHidden = false boostView.isHidden = true replyView.isHidden = true - bottomDividerView.isHidden = false attachmentsView.backgroundColor = UIColor.white attachmentsView.isHidden = true @@ -242,62 +240,58 @@ class StatusView: UIView { } if let content = status.content { - do { - let styledContent = " \(content)" - let attributedText = try NSAttributedString( - data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!, - options: [.documentType: NSAttributedString.DocumentType.html], - documentAttributes: nil - ) +// let linkAttributes: [NSAttributedString.Key : Any] = [ +// NSAttributedString.Key.foregroundColor: UIColor(named: "Primary")!, +// NSAttributedString.Key.underlineColor: UIColor(named: "Primary")!, +// NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single, +// ] + + contentTextView.attributedText = content.htmlAttributed(size: 15.0) + //contentTextView.linkTextAttributes = linkAttributes + + if status.hidden && spoilerView == nil { + let spoilerText = UILabel(frame: contentTextView.frame) + spoilerText.textColor = UIColor(named: "Primary") + spoilerText.font = UIFont.systemFont(ofSize: 15, weight: .bold) + spoilerText.textAlignment = .center + spoilerText.text = status.spoilerText + spoilerText.numberOfLines = 0 + spoilerText.translatesAutoresizingMaskIntoConstraints = false + + let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.light)) + blurEffectView.translatesAutoresizingMaskIntoConstraints = false + blurEffectView.contentView.addSubview(spoilerText) + + NSLayoutConstraint.activate([ + spoilerText.leadingAnchor.constraint(equalTo: blurEffectView.leadingAnchor), + spoilerText.trailingAnchor.constraint(equalTo: blurEffectView.trailingAnchor), + spoilerText.centerYAnchor.constraint(equalTo: blurEffectView.centerYAnchor), + ]) - contentLabel.attributedText = attributedText + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.reveal)) + tapGesture.numberOfTapsRequired = 1 + tapGesture.numberOfTouchesRequired = 1 + blurEffectView.addGestureRecognizer(tapGesture) + blurEffectView.isUserInteractionEnabled = true + + self.spoilerView = blurEffectView + self.contentView.addSubview(blurEffectView) + + NSLayoutConstraint.activate([ + blurEffectView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + blurEffectView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + blurEffectView.topAnchor.constraint(equalTo: contentTextView.topAnchor), + blurEffectView.bottomAnchor.constraint(equalTo: detailsView.topAnchor), + ]) + } else { + if let spoilerView = spoilerView { + spoilerView.removeFromSuperview() + self.spoilerView = nil + } - if status.hidden && spoilerView == nil { - let spoilerText = UILabel(frame: contentLabel.frame) - spoilerText.textColor = UIColor(named: "Primary") - spoilerText.font = UIFont.systemFont(ofSize: 15, weight: .bold) - spoilerText.textAlignment = .center - spoilerText.text = status.spoilerText - spoilerText.numberOfLines = 0 - spoilerText.translatesAutoresizingMaskIntoConstraints = false - - let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.light)) - blurEffectView.translatesAutoresizingMaskIntoConstraints = false - blurEffectView.contentView.addSubview(spoilerText) - - NSLayoutConstraint.activate([ - spoilerText.leadingAnchor.constraint(equalTo: blurEffectView.leadingAnchor), - spoilerText.trailingAnchor.constraint(equalTo: blurEffectView.trailingAnchor), - spoilerText.centerYAnchor.constraint(equalTo: blurEffectView.centerYAnchor), - ]) - - let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.reveal)) - tapGesture.numberOfTapsRequired = 1 - tapGesture.numberOfTouchesRequired = 1 - blurEffectView.addGestureRecognizer(tapGesture) - blurEffectView.isUserInteractionEnabled = true - - self.spoilerView = blurEffectView - self.contentView.addSubview(blurEffectView) - - NSLayoutConstraint.activate([ - blurEffectView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), - blurEffectView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), - blurEffectView.topAnchor.constraint(equalTo: contentLabel.topAnchor), - blurEffectView.bottomAnchor.constraint(equalTo: detailsView.topAnchor), - ]) - } else { - if let spoilerView = spoilerView { - spoilerView.removeFromSuperview() - self.spoilerView = nil - } - - if let spoilerText = status.spoilerText, !spoilerText.isEmpty { - spoilerImageView.isHidden = false - } + if let spoilerText = status.spoilerText, !spoilerText.isEmpty { + spoilerImageView.isHidden = false } - } catch { - print("\(error)") } } diff --git a/elpha-ios/StatusView.xib b/elpha-ios/StatusView.xib index b7ad6cc..c05c51f 100644 --- a/elpha-ios/StatusView.xib +++ b/elpha-ios/StatusView.xib @@ -22,7 +22,7 @@ - + @@ -226,12 +226,6 @@ - @@ -272,17 +266,26 @@ + + + + + + + + + - + + + - - - + diff --git a/elpha-ios/String+HtmlAttributed.swift b/elpha-ios/String+HtmlAttributed.swift new file mode 100644 index 0000000..9dc2e70 --- /dev/null +++ b/elpha-ios/String+HtmlAttributed.swift @@ -0,0 +1,40 @@ +// +// String+HtmlAttributed.swift +// elpha-ios +// +// Created by Dwayne Harris on 11/6/18. +// Copyright © 2018 Elpha. All rights reserved. +// + +import UIKit + +extension String { + func htmlAttributed(size: CGFloat, centered: Bool = false) -> NSAttributedString? { + do { + let htmlString = """ + + \(self) + """ + + guard let data = htmlString.data(using: String.Encoding.utf16) else { + return nil + } + + return try NSAttributedString( + data: data, + options: [.documentType: NSAttributedString.DocumentType.html], + documentAttributes: nil + ) + } catch { + print("\(error)") + return nil + } + } +} diff --git a/elpha-ios/UIColor+HexString.swift b/elpha-ios/UIColor+HexString.swift new file mode 100644 index 0000000..f203dd2 --- /dev/null +++ b/elpha-ios/UIColor+HexString.swift @@ -0,0 +1,23 @@ +// +// UIColor+HexString.swift +// elpha-ios +// +// Created by Dwayne Harris on 11/6/18. +// Copyright © 2018 Elpha. All rights reserved. +// + +import UIKit + +extension UIColor { + func hexString() -> String { + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + var a: CGFloat = 0 + + getRed(&r, green: &g, blue: &b, alpha: &a) + + let rgb: Int = (Int)(r * 255) << 16 | (Int)(g * 255) << 8 | (Int)(b * 255) << 0 + return String(format: "#%06x", rgb) + } +}