diff --git a/elpha-ios.xcodeproj/project.pbxproj b/elpha-ios.xcodeproj/project.pbxproj index fc19a1e..8f0abb7 100644 --- a/elpha-ios.xcodeproj/project.pbxproj +++ b/elpha-ios.xcodeproj/project.pbxproj @@ -24,6 +24,8 @@ 152FBCEE219799FC0079B3E8 /* FLAnimatedImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 152FBCEC219799E50079B3E8 /* FLAnimatedImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 152FBCF2219818AD0079B3E8 /* FieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FBCF1219818AD0079B3E8 /* FieldTableViewCell.swift */; }; 1539509121894A38009BA6E7 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1539509021894A38009BA6E7 /* AlertManager.swift */; }; + 156902A0219A7D75002BF61F /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1569029F219A7D75002BF61F /* ComposeViewController.swift */; }; + 156902B3219A8A1C002BF61F /* FLAnimatedImageView+LoadImageURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156902B2219A8A1C002BF61F /* FLAnimatedImageView+LoadImageURL.swift */; }; 156FF015217289380074D9CA /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156FF014217289380074D9CA /* AccountTableViewCell.swift */; }; 156FF0312174797E0074D9CA /* StatusTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156FF0302174797E0074D9CA /* StatusTableViewController.swift */; }; 156FF04F2175CDBC0074D9CA /* MainStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156FF04E2175CDBC0074D9CA /* MainStatusTableViewCell.swift */; }; @@ -256,6 +258,8 @@ 152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FLAnimatedImage.xcodeproj; path = Frameworks/FLAnimatedImage/FLAnimatedImage.xcodeproj; sourceTree = ""; }; 152FBCF1219818AD0079B3E8 /* FieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldTableViewCell.swift; sourceTree = ""; }; 1539509021894A38009BA6E7 /* AlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertManager.swift; sourceTree = ""; }; + 1569029F219A7D75002BF61F /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; + 156902B2219A8A1C002BF61F /* FLAnimatedImageView+LoadImageURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FLAnimatedImageView+LoadImageURL.swift"; sourceTree = ""; }; 156FF014217289380074D9CA /* AccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = ""; }; 156FF0302174797E0074D9CA /* StatusTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewController.swift; sourceTree = ""; }; 156FF04E2175CDBC0074D9CA /* MainStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainStatusTableViewCell.swift; sourceTree = ""; }; @@ -378,6 +382,7 @@ isa = PBXGroup; children = ( 159026CF2163069600D362DD /* Date+TimeAgo.swift */, + 156902B2219A8A1C002BF61F /* FLAnimatedImageView+LoadImageURL.swift */, 15B127912192467F00F4EF1D /* String+HtmlAttributed.swift */, 15B127A22192486200F4EF1D /* UIColor+HexString.swift */, ); @@ -500,6 +505,7 @@ 152FB0F7218ADC1A001D6574 /* AttachmentPageViewController.swift */, 152FB0F9218ADDD0001D6574 /* AttachmentViewController.swift */, 15960E7D21329FED00C38CE9 /* AuthenticateViewController.swift */, + 1569029F219A7D75002BF61F /* ComposeViewController.swift */, 1506C5922199768A00EFB483 /* InstancesNavigationController.swift */, 15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */, 157405A72150588A00EEAAEB /* InstanceViewController.swift */, @@ -751,6 +757,7 @@ 156FF0312174797E0074D9CA /* StatusTableViewController.swift in Sources */, 152FB0F8218ADC1A001D6574 /* AttachmentPageViewController.swift in Sources */, 15131EF4216DB8B90092B252 /* AccountTableViewController.swift in Sources */, + 156902A0219A7D75002BF61F /* ComposeViewController.swift in Sources */, 15F998352162C0E8009E58DA /* MastodonDataManager.swift in Sources */, 15960E7A2132387A00C38CE9 /* MainTabBarController.swift in Sources */, 15960E7C213272CD00C38CE9 /* AuthenticationManager.swift in Sources */, @@ -773,6 +780,7 @@ 159026D02163069600D362DD /* Date+TimeAgo.swift in Sources */, 152FBCD2219682E80079B3E8 /* AbstractStatusTableViewController.swift in Sources */, 15A79B43215EB959007A326E /* CoreDataManager.swift in Sources */, + 156902B3219A8A1C002BF61F /* FLAnimatedImageView+LoadImageURL.swift in Sources */, 15BB72AB2171A8D4002F1FA4 /* TimelinesTableViewCell.swift in Sources */, 1574148D2169AD0100C841BD /* AttachmentManager.swift in Sources */, 156FF015217289380074D9CA /* AccountTableViewCell.swift in Sources */, diff --git a/elpha-ios/AbstractStatusTableViewController.swift b/elpha-ios/AbstractStatusTableViewController.swift index e5bda41..8ea8ef3 100644 --- a/elpha-ios/AbstractStatusTableViewController.swift +++ b/elpha-ios/AbstractStatusTableViewController.swift @@ -48,6 +48,10 @@ class AbstractStatusTableViewController: UITableViewController, StatusViewDelega } + func replyTapped(status: StatusMO) { + performSegue(withIdentifier: "ComposeSegue", sender: self) + } + func attachmentTapped(status: StatusMO, index: Int) { let storyboard = UIStoryboard(name: "Main", bundle: nil) diff --git a/elpha-ios/AccountTableViewController.swift b/elpha-ios/AccountTableViewController.swift index 9e88303..486a02f 100644 --- a/elpha-ios/AccountTableViewController.swift +++ b/elpha-ios/AccountTableViewController.swift @@ -8,6 +8,7 @@ import AlamofireImage import CoreData +import FLAnimatedImage import UIKit import SafariServices @@ -65,7 +66,7 @@ class FieldTableViewController: NSObject, UITableViewDelegate, UITableViewDataSo class AccountTableViewController: AbstractStatusTableViewController { @IBOutlet var headerView: UIView! @IBOutlet var headerImageView: UIImageView! - @IBOutlet var avatarImageView: UIImageView! + @IBOutlet var avatarImageView: FLAnimatedImageView! @IBOutlet var displayNameLabel: UILabel! @IBOutlet var usernameLabel: UILabel! @IBOutlet var statusesLabel: UILabel! @@ -101,18 +102,12 @@ class AccountTableViewController: AbstractStatusTableViewController { private func updateHeader(withAccount account: AccountMO) { navigationItem.title = account.displayName - let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter( - size: CGSize(width: 70.0, height: 70.0), - radius: 20.0, - divideRadiusByImageScale: true - ) - if let headerURL = account.headerURL { headerImageView.af_setImage(withURL: headerURL) } if let avatarURL = account.avatarURL { - avatarImageView.af_setImage(withURL: avatarURL, filter: avatarFilter) + avatarImageView.loadImageURL(avatarURL) } displayNameLabel.text = account.displayName @@ -148,6 +143,8 @@ class AccountTableViewController: AbstractStatusTableViewController { avatarImageView.layer.shadowOpacity = 0.8 avatarImageView.layer.shadowOffset = CGSize.zero avatarImageView.layer.shadowRadius = 10 + avatarImageView.layer.cornerRadius = 10 + avatarImageView.layer.masksToBounds = true if self.account == nil { if let session = AuthenticationManager.session { diff --git a/elpha-ios/Assets.xcassets/Icons/Close White.imageset/Contents.json b/elpha-ios/Assets.xcassets/Icons/Close White.imageset/Contents.json new file mode 100644 index 0000000..58a1f2d --- /dev/null +++ b/elpha-ios/Assets.xcassets/Icons/Close White.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "x-square.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Icons/Close White.imageset/x-square.pdf b/elpha-ios/Assets.xcassets/Icons/Close White.imageset/x-square.pdf new file mode 100644 index 0000000..35aead3 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Icons/Close White.imageset/x-square.pdf differ diff --git a/elpha-ios/Assets.xcassets/Icons/Close.imageset/x-square.pdf b/elpha-ios/Assets.xcassets/Icons/Close.imageset/x-square.pdf index 35aead3..92f4427 100644 Binary files a/elpha-ios/Assets.xcassets/Icons/Close.imageset/x-square.pdf and b/elpha-ios/Assets.xcassets/Icons/Close.imageset/x-square.pdf differ diff --git a/elpha-ios/Assets.xcassets/Icons/Help.imageset/help-circle.pdf b/elpha-ios/Assets.xcassets/Icons/Help.imageset/help-circle.pdf index fc7c255..87e15d4 100644 Binary files a/elpha-ios/Assets.xcassets/Icons/Help.imageset/help-circle.pdf and b/elpha-ios/Assets.xcassets/Icons/Help.imageset/help-circle.pdf differ diff --git a/elpha-ios/AttachmentManager.swift b/elpha-ios/AttachmentManager.swift index 4b88a5b..dd059b6 100644 --- a/elpha-ios/AttachmentManager.swift +++ b/elpha-ios/AttachmentManager.swift @@ -17,10 +17,6 @@ protocol AttachmentManagerDelegate { class AttachmentManager: NSObject { var delegate: AttachmentManagerDelegate? = nil - static private var downloader = ImageDownloader() - static private var imageCache = AutoPurgingImageCache() - static private let placeholderImage = UIImage(named: "Placeholder") - @objc func attachmentTapped(_ gestureRecognizer: UITapGestureRecognizer) { if let delegate = delegate, let name = gestureRecognizer.name { delegate.attachmentTapped(index: Int(name)!) @@ -42,8 +38,6 @@ class AttachmentManager: NSObject { case 0: return case 1: - let filter = AspectScaledToFillSizeFilter(size: CGSize(width: view.frame.width, height: view.frame.width)) - let attachment = attachments.firstObject as! AttachmentMO let imageView = FLAnimatedImageView() @@ -55,20 +49,8 @@ class AttachmentManager: NSObject { imageView.addGestureRecognizer(tapGestureRecognizer) imageView.isUserInteractionEnabled = true - imageView.contentMode = UIImageView.ContentMode.center - imageView.image = AttachmentManager.placeholderImage - let request = URLRequest(url: attachment.url!) - AttachmentManager.downloader.download(request, filter: filter) { response in - imageView.contentMode = UIImageView.ContentMode.scaleAspectFill - - switch attachment.type { - case "gif": - imageView.animatedImage = FLAnimatedImage(animatedGIFData: response.data) - default: - imageView.image = response.result.value - } - } + imageView.loadImageURL(attachment.url!) view.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false @@ -80,8 +62,6 @@ class AttachmentManager: NSObject { imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) case 2: - let filter = AspectScaledToFillSizeFilter(size: CGSize(width: halfWidth, height: view.frame.width)) - let imageViews = [ FLAnimatedImageView(), FLAnimatedImageView(), @@ -99,10 +79,7 @@ class AttachmentManager: NSObject { imageView.addGestureRecognizer(tapGestureRecognizer) imageView.isUserInteractionEnabled = true - imageView.af_setImage( - withURL: (attachments[index] as! AttachmentMO).url!, - filter: filter - ) + imageView.loadImageURL((attachments[index] as! AttachmentMO).url!) view.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false @@ -119,9 +96,6 @@ class AttachmentManager: NSObject { imageViews[1].trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) case 3: - let primaryFilter = AspectScaledToFillSizeFilter(size: CGSize(width: halfWidth, height: view.frame.width)) - let secondaryFilter = AspectScaledToFillSizeFilter(size: CGSize(width: halfWidth, height: halfWidth)) - let imageViews = [ FLAnimatedImageView(), FLAnimatedImageView(), @@ -140,10 +114,7 @@ class AttachmentManager: NSObject { imageView.addGestureRecognizer(tapGestureRecognizer) imageView.isUserInteractionEnabled = true - imageView.af_setImage( - withURL: (attachments[index] as! AttachmentMO).url!, - filter: index == 0 ? primaryFilter : secondaryFilter - ) + imageView.loadImageURL((attachments[index] as! AttachmentMO).url!) view.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false @@ -169,8 +140,6 @@ class AttachmentManager: NSObject { imageViews[2].bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) default: - let filter = AspectScaledToFillSizeFilter(size: CGSize(width: halfWidth, height: halfWidth)) - let imageViews = [ FLAnimatedImageView(), FLAnimatedImageView(), @@ -190,10 +159,7 @@ class AttachmentManager: NSObject { imageView.addGestureRecognizer(tapGestureRecognizer) imageView.isUserInteractionEnabled = true - imageView.af_setImage( - withURL: (attachments[index] as! AttachmentMO).url!, - filter: filter - ) + imageView.loadImageURL((attachments[index] as! AttachmentMO).url!) view.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false diff --git a/elpha-ios/AttachmentViewController.swift b/elpha-ios/AttachmentViewController.swift index 692f93c..0910fb1 100644 --- a/elpha-ios/AttachmentViewController.swift +++ b/elpha-ios/AttachmentViewController.swift @@ -6,11 +6,12 @@ // Copyright © 2018 Elpha. All rights reserved. // +import FLAnimatedImage import UIKit class AttachmentViewController: UIViewController { @IBOutlet var attachmentScrollView: UIScrollView! - @IBOutlet var attachmentImageView: UIImageView! + @IBOutlet var attachmentImageView: FLAnimatedImageView! @IBOutlet var statusTextView: UITextView! var attachment: AttachmentMO? = nil @@ -33,7 +34,7 @@ class AttachmentViewController: UIViewController { if let attachment = attachment { attachmentScrollView.delegate = self - attachmentImageView.af_setImage(withURL: attachment.url!) + attachmentImageView.loadImageURL(attachment.url!) if let content = attachment.status?.content { statusTextView.attributedText = content.htmlAttributed(size: 14, centered: true, color: UIColor.white) diff --git a/elpha-ios/Base.lproj/Main.storyboard b/elpha-ios/Base.lproj/Main.storyboard index 0da517d..a681866 100644 --- a/elpha-ios/Base.lproj/Main.storyboard +++ b/elpha-ios/Base.lproj/Main.storyboard @@ -493,7 +493,7 @@ - + @@ -807,7 +807,7 @@ - + @@ -1059,99 +1059,251 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + @@ -1199,6 +1351,7 @@ + @@ -1224,7 +1377,7 @@ - + @@ -1543,7 +1696,7 @@ - + diff --git a/elpha-ios/ComposeViewController.swift b/elpha-ios/ComposeViewController.swift new file mode 100644 index 0000000..fc651ea --- /dev/null +++ b/elpha-ios/ComposeViewController.swift @@ -0,0 +1,64 @@ +// +// ComposeViewController.swift +// elpha-ios +// +// Created by Dwayne Harris on 11/12/18. +// Copyright © 2018 Elpha. All rights reserved. +// + +import FLAnimatedImage +import UIKit + +class ComposeViewController: UIViewController { + @IBOutlet var replyToView: UIView! + @IBOutlet var replyToAvatarImageView: FLAnimatedImageView! + @IBOutlet var replyToDisplayNameLabel: UILabel! + @IBOutlet var replyToUsernameLabel: UILabel! + @IBOutlet var replyToContentTextView: UITextViewFixed! + @IBOutlet var statusTextField: UITextField! + @IBOutlet var statusCharacterCountLabel: UILabel! + @IBOutlet var contentWarningTextField: UITextField! + @IBOutlet var tootButton: UIButton! + + var replyToStatus: StatusMO? = nil + + override func viewDidLoad() { + super.viewDidLoad() + + if let replyToStatus = replyToStatus { + replyToView.isHidden = false + + if let reblog = replyToStatus.reblog { + self.setupReplyTo(status: reblog) + } else { + self.setupReplyTo(status: replyToStatus) + } + } else { + replyToView.isHidden = true + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + statusTextField.becomeFirstResponder() + } + + func setupReplyTo(status: StatusMO) { + if let account = status.account { + replyToAvatarImageView.loadImageURL(account.avatarURL!) + replyToDisplayNameLabel.text = account.displayName + replyToUsernameLabel.text = "@\(account.acct!)" + } + + replyToContentTextView.attributedText = status.content?.htmlAttributed(size: 15.0) + } + + @IBAction func statusTextFieldEdited(_ sender: Any) { + let characters = statusTextField.text!.count + statusCharacterCountLabel.text = String(500 - characters) + } + + @IBAction func dismissTapped(_ sender: Any) { + dismiss(animated: true) + } +} diff --git a/elpha-ios/FLAnimatedImageView+LoadImageURL.swift b/elpha-ios/FLAnimatedImageView+LoadImageURL.swift new file mode 100644 index 0000000..93371e3 --- /dev/null +++ b/elpha-ios/FLAnimatedImageView+LoadImageURL.swift @@ -0,0 +1,78 @@ +// +// FLAnimatedImage+LoadImageURL.swift +// elpha-ios +// +// Created by Dwayne Harris on 11/12/18. +// Copyright © 2018 Elpha. All rights reserved. +// + +import Alamofire +import AlamofireImage +import FLAnimatedImage +import Foundation + +class ImageCache { + static var cache: NSCache = NSCache() + + static func set(string: String, data: Data) { + ImageCache.cache.setObject(data as AnyObject, forKey: string as AnyObject) + } + + static func set(url: URL, data: Data) { + set(string: url.absoluteString, data: data) + } + + static func set(request: URLRequest, data: Data) { + set(url: request.url!, data: data) + } + + static func get(string: String) -> Data? { + if let data = ImageCache.cache.object(forKey: string as AnyObject) as? Data { + return data + } else { + return nil + } + } + + static func get(url: URL) -> Data? { + return get(string: url.absoluteString) + } + + static func get(request: URLRequest) -> Data? { + return get(url: request.url!) + } +} + +extension FLAnimatedImageView { + func setPlaceholder() { + self.contentMode = .center + self.image = UIImage(named: "Help") + } + + func loadImageURL(_ url: URL) { + if let data = ImageCache.get(url: url) { + if url.absoluteString.hasSuffix(".gif") { + self.animatedImage = FLAnimatedImage(animatedGIFData: data) + } else { + self.image = UIImage(data: data) + } + } else { + setPlaceholder() + + Alamofire.request(url).responseImage { response in + if let data = response.data { + DispatchQueue.main.async { + ImageCache.set(url: url, data: data) + self.contentMode = .scaleAspectFit + + if url.absoluteString.hasSuffix(".gif") { + self.animatedImage = FLAnimatedImage(animatedGIFData: data) + } else { + self.image = UIImage(data: data) + } + } + } + } + } + } +} diff --git a/elpha-ios/MainStatusTableViewCell.swift b/elpha-ios/MainStatusTableViewCell.swift index edd05e5..c5a27c2 100644 --- a/elpha-ios/MainStatusTableViewCell.swift +++ b/elpha-ios/MainStatusTableViewCell.swift @@ -6,10 +6,11 @@ // Copyright © 2018 Elpha. All rights reserved. // +import FLAnimatedImage import UIKit class MainStatusTableViewCell: UITableViewCell { - @IBOutlet var avatarImageView: UIImageView! + @IBOutlet var avatarImageView: FLAnimatedImageView! @IBOutlet var displayNameLabel: UILabel! @IBOutlet var usernameLabel: UILabel! @IBOutlet var repliesImageView: UIImageView! diff --git a/elpha-ios/SettingsTableViewController.swift b/elpha-ios/SettingsTableViewController.swift index ac72db6..e5a130f 100644 --- a/elpha-ios/SettingsTableViewController.swift +++ b/elpha-ios/SettingsTableViewController.swift @@ -7,11 +7,12 @@ // import AlamofireImage +import FLAnimatedImage import UIKit class SettingsTableViewController: UITableViewController { @IBOutlet var headerImageView: UIImageView! - @IBOutlet var avatarImageView: UIImageView! + @IBOutlet var avatarImageView: FLAnimatedImageView! @IBOutlet var displayNameLabel: UILabel! @IBOutlet var usernameLabel: UILabel! @@ -20,20 +21,16 @@ class SettingsTableViewController: UITableViewController { navigationItem.title = "Settings" - let filter = AspectScaledToFillSizeWithRoundedCornersFilter( - size: CGSize(width: 70.0, height: 70.0), - radius: 20.0, - divideRadiusByImageScale: true - ) - avatarImageView.layer.shadowColor = UIColor.black.cgColor avatarImageView.layer.shadowOpacity = 0.8 avatarImageView.layer.shadowOffset = CGSize.zero avatarImageView.layer.shadowRadius = 10 + avatarImageView.layer.cornerRadius = 10 + avatarImageView.layer.masksToBounds = true if let account = AuthenticationManager.session?.account { headerImageView.af_setImage(withURL: account.headerURL!) - avatarImageView.af_setImage(withURL: account.avatarURL!, filter: filter) + avatarImageView.loadImageURL(account.avatarURL!) displayNameLabel.text = account.displayName usernameLabel.text = "@\(account.acct!)" } diff --git a/elpha-ios/StatusTableViewController.swift b/elpha-ios/StatusTableViewController.swift index a692666..eb791aa 100644 --- a/elpha-ios/StatusTableViewController.swift +++ b/elpha-ios/StatusTableViewController.swift @@ -262,15 +262,16 @@ extension StatusTableViewController { fatalError("Unable to find reusable cell") } - let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter( - size: CGSize(width: 40.0, height: 40.0), - radius: 30.0, - divideRadiusByImageScale: true - ) + cell.avatarImageView.layer.shadowColor = UIColor.black.cgColor + cell.avatarImageView.layer.shadowOpacity = 0.8 + cell.avatarImageView.layer.shadowOffset = CGSize.zero + cell.avatarImageView.layer.shadowRadius = 10 + cell.avatarImageView.layer.cornerRadius = 10 + cell.avatarImageView.layer.masksToBounds = true func updateAccountView(status: StatusMO) { if let account = status.account { - cell.avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter) + cell.avatarImageView.loadImageURL(account.avatarURL!) cell.displayNameLabel.text = account.displayName cell.usernameLabel.text = "@\(account.acct!)" } diff --git a/elpha-ios/StatusView.swift b/elpha-ios/StatusView.swift index f94ce60..6c7d3e9 100644 --- a/elpha-ios/StatusView.swift +++ b/elpha-ios/StatusView.swift @@ -7,6 +7,7 @@ // import AlamofireImage +import FLAnimatedImage import UIKit protocol StatusViewDelegate { @@ -17,6 +18,7 @@ protocol StatusViewDelegate { func urlTapped(url: URL) func boostTapped() func favoriteTapped() + func replyTapped(status: StatusMO) func revealTapped() func hideTapped() } @@ -25,6 +27,7 @@ extension StatusViewDelegate { func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {} func boostTapped() {} func favoriteTapped() {} + func replyTapped(status: StatusMO) {} func revealTapped() {} func hideTapped() {} } @@ -32,14 +35,14 @@ extension StatusViewDelegate { class StatusView: UIView { @IBOutlet var contentView: UIView! @IBOutlet var boostView: UIView! - @IBOutlet var boostAvatarImageView: UIImageView! + @IBOutlet var boostAvatarImageView: FLAnimatedImageView! @IBOutlet var boostDisplayNameLabel: UILabel! @IBOutlet var boostUsernameLabel: UILabel! @IBOutlet var replyView: UIView! - @IBOutlet var replyAvatarImageView: UIImageView! + @IBOutlet var replyAvatarImageView: FLAnimatedImageView! @IBOutlet var replyDisplayNameLabel: UILabel! @IBOutlet var replyUsernameLabel: UILabel! - @IBOutlet var avatarImageView: UIImageView! + @IBOutlet var avatarImageView: FLAnimatedImageView! @IBOutlet var displayNameLabel: UILabel! @IBOutlet var usernameLabel: UILabel! @IBOutlet var timestampLabel: UILabel! @@ -198,6 +201,9 @@ class StatusView: UIView { } } + @IBAction func replyTapped(_ sender: Any) { + delegate?.replyTapped(status: status!) + } @objc func reveal(sender: UITapGestureRecognizer) { if let status = status { @@ -224,6 +230,13 @@ class StatusView: UIView { attachmentManager.delegate = self contentTextView.delegate = self feedbackGenerator = UINotificationFeedbackGenerator() + + avatarImageView.layer.cornerRadius = 10 + avatarImageView.layer.masksToBounds = true + boostAvatarImageView.layer.cornerRadius = 10 + boostAvatarImageView.layer.masksToBounds = true + replyAvatarImageView.layer.cornerRadius = 10 + replyAvatarImageView.layer.masksToBounds = true } public func update(withStatus status: StatusMO) { @@ -235,15 +248,9 @@ class StatusView: UIView { attachmentsView.isHidden = true spoilerImageView.isHidden = true - let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter( - size: CGSize(width: 40.0, height: 40.0), - radius: 20.0, - divideRadiusByImageScale: true - ) - func updateStatusContent(_ status: StatusMO) { if let account = status.account { - avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter) + avatarImageView.loadImageURL(account.avatarURL!) displayNameLabel.text = account.displayName usernameLabel.text = "@\(account.acct!)" } @@ -326,7 +333,7 @@ class StatusView: UIView { boostView.isHidden = false if let account = status.account { - boostAvatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter) + boostAvatarImageView.loadImageURL(account.avatarURL!) boostDisplayNameLabel.text = account.displayName boostUsernameLabel.text = "@\(account.acct!)" } @@ -334,7 +341,7 @@ class StatusView: UIView { updateStatusContent(reblog) } else { if let account = status.account { - avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter) + avatarImageView.loadImageURL(account.avatarURL!) displayNameLabel.text = account.displayName usernameLabel.text = "@\(account.acct!)" } @@ -345,7 +352,7 @@ class StatusView: UIView { if let replyAccountID = status.inReplyToAccountID { if let replyAccount = MastodonDataManager.account(id: replyAccountID) { replyView.isHidden = false - replyAvatarImageView.af_setImage(withURL: replyAccount.avatarURL!, filter: avatarFilter) + replyAvatarImageView.loadImageURL(replyAccount.avatarURL!) replyDisplayNameLabel.text = replyAccount.displayName replyUsernameLabel.text = "@\(replyAccount.acct!)" } diff --git a/elpha-ios/StatusView.xib b/elpha-ios/StatusView.xib index ea369d5..87a936c 100644 --- a/elpha-ios/StatusView.xib +++ b/elpha-ios/StatusView.xib @@ -91,7 +91,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -230,7 +230,7 @@ - + @@ -430,6 +430,7 @@ + @@ -438,6 +439,9 @@ + + + @@ -556,6 +560,11 @@ + + + + + diff --git a/elpha-ios/TimelineTableViewController.swift b/elpha-ios/TimelineTableViewController.swift index 5635df2..339cf04 100644 --- a/elpha-ios/TimelineTableViewController.swift +++ b/elpha-ios/TimelineTableViewController.swift @@ -16,6 +16,8 @@ class TimelineTableViewController: AbstractStatusTableViewController { var feedbackGenerator: UINotificationFeedbackGenerator? = nil var fetchedResultsController: NSFetchedResultsController? = nil + var replyToStatus: StatusMO? = nil + override var currentPaginationContext: String { get { guard let timeline = AuthenticationManager.session?.timeline, let categoryString = timeline.category else { @@ -99,6 +101,11 @@ class TimelineTableViewController: AbstractStatusTableViewController { } } + override func replyTapped(status: StatusMO) { + replyToStatus = status + performSegue(withIdentifier: "ComposeSegue", sender: self) + } + @objc func openSettings() { let storyboard = UIStoryboard(name: "Main", bundle: nil) @@ -111,16 +118,23 @@ class TimelineTableViewController: AbstractStatusTableViewController { performSegue(withIdentifier: "TimelinesSegue", sender: self) } + @objc func compose() { + replyToStatus = nil + performSegue(withIdentifier: "ComposeSegue", sender: self) + } + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "TimelinesSegue" { if let destination = segue.destination as? TimelinesViewController { destination.delegate = self } } - } - - @objc func compose() { - AlertManager.shared.show(message: "We'll get the compose screen working one day.") + + if segue.identifier == "ComposeSegue" { + if let destination = segue.destination as? ComposeViewController { + destination.replyToStatus = replyToStatus + } + } } func createDefaultTimelines(account: AccountMO) {