// // ComposeViewController.swift // elpha-ios // // Created by Dwayne Harris on 11/12/18. // Copyright © 2018 Elpha. All rights reserved. // import Kingfisher import UIKit class ComposeViewController: UIViewController { @IBOutlet var replyToView: UIView! @IBOutlet var replyToAvatarImageView: UIImageView! @IBOutlet var replyToDisplayNameLabel: UILabel! @IBOutlet var replyToUsernameLabel: UILabel! @IBOutlet var replyToContentTextView: UITextViewFixed! @IBOutlet var statusTextView: UITextView! @IBOutlet var statusCharacterCountLabel: UILabel! @IBOutlet var contentWarningTextField: UITextField! @IBOutlet var bottomConstraint: NSLayoutConstraint! let characterLimit = 500 let composeAccessoryViewHeight: CGFloat = 55.0 var feedbackGenerator: UINotificationFeedbackGenerator? var replyToStatus: StatusMO? var composeAccessoryView: ComposeAccessoryView? var selectedVisibility: StatusVisibility = .public var attachmentInputView: AttachmentInputView? var visibilityInputView: VisibilityInputView? override func viewDidLoad() { super.viewDidLoad() feedbackGenerator = UINotificationFeedbackGenerator() statusTextView.layer.cornerRadius = 10 statusTextView.layer.masksToBounds = true statusTextView.textContainerInset = UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5) replyToAvatarImageView.setRoundedCorners() composeAccessoryView = ComposeAccessoryView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: composeAccessoryViewHeight)) composeAccessoryView!.delegate = self composeAccessoryView!.selectedVisibility = selectedVisibility visibilityInputView = VisibilityInputView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 250)) visibilityInputView!.delegate = self attachmentInputView = AttachmentInputView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 400)) statusTextView.delegate = self statusTextView.inputAccessoryView = composeAccessoryView statusCharacterCountLabel.text = String(characterLimit) NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotification(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) 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 } } deinit { NotificationCenter.default.removeObserver(self) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) statusTextView.becomeFirstResponder() } func setupReplyTo(status: StatusMO) { if let account = status.account { let options: KingfisherOptionsInfo = SettingsManager.automaticallyPlayGIFs ? [] : [.onlyLoadFirstFrame] replyToAvatarImageView.kf.setImage(with: account.avatarURL!, options: options) replyToDisplayNameLabel.text = account.displayName replyToUsernameLabel.text = "@\(account.acct!)" statusTextView.text = "@\(account.acct!) " } replyToContentTextView.attributedText = status.content?.htmlAttributed(size: 13.0) } @objc func keyboardNotification(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { bottomConstraint.constant = keyboardSize.height + 10 } } @IBAction func dismissTapped(_ sender: Any) { dismiss(animated: true) } } extension ComposeViewController: UITextViewDelegate { func textViewDidChange(_ textView: UITextView) { let characters = statusTextView.text!.count let remainingCharacters = characterLimit - characters statusCharacterCountLabel.text = String(remainingCharacters) statusCharacterCountLabel.textColor = remainingCharacters < 1 ? UIColor.red : UIColor(named: "Primary") } } extension ComposeViewController: ComposeAccessoryViewDelegate, VisibilityInputViewDelegate { func attachmentTapped(_ sender: Any) { statusTextView.inputView = statusTextView.inputView == nil ? attachmentInputView : nil statusTextView.reloadInputViews() } func visibilityTapped(_ sender: Any) { statusTextView.inputView = statusTextView.inputView == nil ? visibilityInputView : nil statusTextView.reloadInputViews() } func tootTapped(_ sender: Any) { if let content = statusTextView.text { if !content.isEmpty && content.count <= characterLimit { feedbackGenerator?.prepare() MastodonAPI.postStatus(content: content, replyToID: replyToStatus?.id, spoilerText: contentWarningTextField.text, visibility: selectedVisibility) { error in guard error == nil else { self.feedbackGenerator?.notificationOccurred(.error) AlertManager.shared.show(message: "Couldn't toot!", category: .error) return } self.feedbackGenerator?.notificationOccurred(.success) AlertManager.shared.show(message: "Toot!", category: .toot) self.statusTextView.text = "" self.contentWarningTextField.text = "" self.dismiss(animated: true) } } } } func visibilitySelected(_ sender: Any, visibility: StatusVisibility) { selectedVisibility = visibility composeAccessoryView?.selectedVisibility = visibility statusTextView.inputView = nil statusTextView.reloadInputViews() } }