forked from shadowfacts/Tusker
Store in reply to status in drafts
This commit is contained in:
parent
681cdb8bb5
commit
0c78af7d4f
|
@ -39,8 +39,8 @@ class DraftsManager: Codable {
|
||||||
return drafts.sorted(by: { $0.lastModified > $1.lastModified })
|
return drafts.sorted(by: { $0.lastModified > $1.lastModified })
|
||||||
}
|
}
|
||||||
|
|
||||||
func create(text: String, contentWarning: String?, attachments: [DraftAttachment]) -> Draft {
|
func create(text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment]) -> Draft {
|
||||||
let draft = Draft(text: text, contentWarning: contentWarning, lastModified: Date(), attachments: attachments)
|
let draft = Draft(text: text, contentWarning: contentWarning, inReplyToID: inReplyToID, attachments: attachments)
|
||||||
drafts.append(draft)
|
drafts.append(draft)
|
||||||
return draft
|
return draft
|
||||||
}
|
}
|
||||||
|
@ -57,15 +57,17 @@ extension DraftsManager {
|
||||||
let id: UUID
|
let id: UUID
|
||||||
private(set) var text: String
|
private(set) var text: String
|
||||||
private(set) var contentWarning: String?
|
private(set) var contentWarning: String?
|
||||||
private(set) var lastModified: Date
|
|
||||||
private(set) var attachments: [DraftAttachment]
|
private(set) var attachments: [DraftAttachment]
|
||||||
|
private(set) var inReplyToID: String?
|
||||||
|
private(set) var lastModified: Date
|
||||||
|
|
||||||
init(text: String, contentWarning: String?, lastModified: Date, attachments: [DraftAttachment]) {
|
init(text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment], lastModified: Date = Date()) {
|
||||||
self.id = UUID()
|
self.id = UUID()
|
||||||
self.text = text
|
self.text = text
|
||||||
self.contentWarning = contentWarning
|
self.contentWarning = contentWarning
|
||||||
self.lastModified = lastModified
|
self.inReplyToID = inReplyToID
|
||||||
self.attachments = attachments
|
self.attachments = attachments
|
||||||
|
self.lastModified = lastModified
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(text: String, contentWarning: String?, attachments: [DraftAttachment]) {
|
func update(text: String, contentWarning: String?, attachments: [DraftAttachment]) {
|
||||||
|
|
|
@ -57,6 +57,8 @@ class ComposeViewController: UIViewController {
|
||||||
@IBOutlet weak var statusTextView: UITextView!
|
@IBOutlet weak var statusTextView: UITextView!
|
||||||
@IBOutlet weak var placeholderLabel: UILabel!
|
@IBOutlet weak var placeholderLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet weak var inReplyToContainer: UIView!
|
||||||
|
@IBOutlet weak var inReplyToLabel: UILabel!
|
||||||
@IBOutlet weak var contentWarningContainerView: UIView!
|
@IBOutlet weak var contentWarningContainerView: UIView!
|
||||||
@IBOutlet weak var contentWarningTextField: UITextField!
|
@IBOutlet weak var contentWarningTextField: UITextField!
|
||||||
|
|
||||||
|
@ -127,49 +129,7 @@ class ComposeViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let inReplyToID = inReplyToID, let inReplyTo = MastodonCache.status(for: inReplyToID) {
|
updateInReplyTo()
|
||||||
visibility = inReplyTo.visibility
|
|
||||||
if Preferences.shared.contentWarningCopyMode == .doNotCopy {
|
|
||||||
contentWarningEnabled = false
|
|
||||||
contentWarningContainerView.isHidden = true
|
|
||||||
} else {
|
|
||||||
contentWarningEnabled = !inReplyTo.spoilerText.isEmpty
|
|
||||||
contentWarningContainerView.isHidden = !contentWarningEnabled
|
|
||||||
if Preferences.shared.contentWarningCopyMode == .prependRe,
|
|
||||||
!inReplyTo.spoilerText.lowercased().starts(with: "re:") {
|
|
||||||
contentWarningTextField.text = "re: \(inReplyTo.spoilerText)"
|
|
||||||
} else {
|
|
||||||
contentWarningTextField.text = inReplyTo.spoilerText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let replyView = ComposeStatusReplyView.create()
|
|
||||||
replyView.updateUI(for: inReplyTo)
|
|
||||||
stackView.insertArrangedSubview(replyView, at: 0)
|
|
||||||
self.replyView = replyView
|
|
||||||
|
|
||||||
replyAvatarImageViewTopConstraint = replyView.avatarImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8)
|
|
||||||
replyAvatarImageViewTopConstraint!.isActive = true
|
|
||||||
|
|
||||||
let replyLabelContainer = UIView()
|
|
||||||
replyLabelContainer.backgroundColor = .clear
|
|
||||||
replyLabelContainer.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
|
|
||||||
let replyLabel = UILabel()
|
|
||||||
replyLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
replyLabel.text = "In reply to \(inReplyTo.account.realDisplayName)"
|
|
||||||
replyLabel.textColor = .secondaryLabel
|
|
||||||
replyLabelContainer.addSubview(replyLabel)
|
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
replyLabel.leadingAnchor.constraint(equalTo: replyLabelContainer.leadingAnchor, constant: 8),
|
|
||||||
replyLabel.trailingAnchor.constraint(equalTo: replyLabelContainer.trailingAnchor, constant: -8),
|
|
||||||
replyLabel.topAnchor.constraint(equalTo: replyLabelContainer.topAnchor),
|
|
||||||
replyLabel.bottomAnchor.constraint(equalTo: replyLabelContainer.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
stackView.insertArrangedSubview(replyLabelContainer, at: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have to set the font here, because the monospaced digit font is not available in IB
|
// we have to set the font here, because the monospaced digit font is not available in IB
|
||||||
charactersRemainingLabel.font = .monospacedDigitSystemFont(ofSize: 17, weight: .regular)
|
charactersRemainingLabel.font = .monospacedDigitSystemFont(ofSize: 17, weight: .regular)
|
||||||
|
@ -177,13 +137,65 @@ class ComposeViewController: UIViewController {
|
||||||
updatePlaceholder()
|
updatePlaceholder()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(contentWarningTextFieldDidChange), name: UITextField.textDidChangeNotification, object: contentWarningTextField)
|
NotificationCenter.default.addObserver(self, selector: #selector(contentWarningTextFieldDidChange), name: UITextField.textDidChangeNotification, object: contentWarningTextField)
|
||||||
|
}
|
||||||
|
|
||||||
if inReplyToID == nil {
|
func updateInReplyTo() {
|
||||||
|
if let replyView = replyView {
|
||||||
|
replyView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
if let inReplyToID = inReplyToID {
|
||||||
|
if let status = MastodonCache.status(for: inReplyToID) {
|
||||||
|
updateInReplyTo(inReplyTo: status)
|
||||||
|
} else {
|
||||||
|
let loadingVC = LoadingViewController()
|
||||||
|
embedChild(loadingVC)
|
||||||
|
|
||||||
|
MastodonCache.status(for: inReplyToID) { (status) in
|
||||||
|
guard let status = status else { return }
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.updateInReplyTo(inReplyTo: status)
|
||||||
|
loadingVC.removeViewAndController()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
visibility = Preferences.shared.defaultPostVisibility
|
visibility = Preferences.shared.defaultPostVisibility
|
||||||
contentWarningEnabled = false
|
contentWarningEnabled = false
|
||||||
|
|
||||||
|
inReplyToContainer.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateInReplyTo(inReplyTo: Status) {
|
||||||
|
visibility = inReplyTo.visibility
|
||||||
|
if Preferences.shared.contentWarningCopyMode == .doNotCopy {
|
||||||
|
contentWarningEnabled = false
|
||||||
|
contentWarningContainerView.isHidden = true
|
||||||
|
} else {
|
||||||
|
contentWarningEnabled = !inReplyTo.spoilerText.isEmpty
|
||||||
|
contentWarningContainerView.isHidden = !contentWarningEnabled
|
||||||
|
if Preferences.shared.contentWarningCopyMode == .prependRe,
|
||||||
|
!inReplyTo.spoilerText.lowercased().starts(with: "re:") {
|
||||||
|
contentWarningTextField.text = "re: \(inReplyTo.spoilerText)"
|
||||||
|
} else {
|
||||||
|
contentWarningTextField.text = inReplyTo.spoilerText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let replyView = ComposeStatusReplyView.create()
|
||||||
|
replyView.updateUI(for: inReplyTo)
|
||||||
|
stackView.insertArrangedSubview(replyView, at: 0)
|
||||||
|
|
||||||
|
self.replyView = replyView
|
||||||
|
|
||||||
|
replyAvatarImageViewTopConstraint = replyView.avatarImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8)
|
||||||
|
replyAvatarImageViewTopConstraint!.isActive = true
|
||||||
|
|
||||||
|
inReplyToContainer.isHidden = false
|
||||||
|
inReplyToLabel.text = "In reply to \(inReplyTo.account.realDisplayName)"
|
||||||
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
|
||||||
|
@ -338,7 +350,7 @@ class ComposeViewController: UIViewController {
|
||||||
if let currentDraft = self.currentDraft {
|
if let currentDraft = self.currentDraft {
|
||||||
currentDraft.update(text: self.statusTextView.text, contentWarning: cw, attachments: attachments)
|
currentDraft.update(text: self.statusTextView.text, contentWarning: cw, attachments: attachments)
|
||||||
} else {
|
} else {
|
||||||
self.currentDraft = DraftsManager.shared.create(text: self.statusTextView.text, contentWarning: cw, attachments: attachments)
|
self.currentDraft = DraftsManager.shared.create(text: self.statusTextView.text, contentWarning: cw, inReplyToID: inReplyToID, attachments: attachments)
|
||||||
}
|
}
|
||||||
DraftsManager.save()
|
DraftsManager.save()
|
||||||
}
|
}
|
||||||
|
@ -598,9 +610,30 @@ extension ComposeViewController: DraftsTableViewControllerDelegate {
|
||||||
func draftSelectionCanceled() {
|
func draftSelectionCanceled() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldSelectDraft(_ draft: DraftsManager.Draft, completion: @escaping (Bool) -> Void) {
|
||||||
|
if draft.inReplyToID != self.inReplyToID {
|
||||||
|
// todo: better text for this
|
||||||
|
let alertController = UIAlertController(title: "Different Reply", message: "The selected draft is a reply to a different status, do you wish to use it?", preferredStyle: .alert)
|
||||||
|
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) in
|
||||||
|
completion(false)
|
||||||
|
}))
|
||||||
|
alertController.addAction(UIAlertAction(title: "Restore Draft", style: .default, handler: { (_) in
|
||||||
|
completion(true)
|
||||||
|
}))
|
||||||
|
// we can't present the alert ourselves, since the compose VC is already presenting the draft selector
|
||||||
|
// but presenting on the presented view controller seems hacky, is there a better way to do this?
|
||||||
|
presentedViewController!.present(alertController, animated: true)
|
||||||
|
} else {
|
||||||
|
completion(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func draftSelected(_ draft: DraftsManager.Draft) {
|
func draftSelected(_ draft: DraftsManager.Draft) {
|
||||||
self.currentDraft = draft
|
self.currentDraft = draft
|
||||||
|
|
||||||
|
inReplyToID = draft.inReplyToID
|
||||||
|
updateInReplyTo()
|
||||||
|
|
||||||
statusTextView.text = draft.text
|
statusTextView.text = draft.text
|
||||||
contentWarningEnabled = draft.contentWarning != nil
|
contentWarningEnabled = draft.contentWarning != nil
|
||||||
contentWarningTextField.text = draft.contentWarning
|
contentWarningTextField.text = draft.contentWarning
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -15,6 +15,8 @@
|
||||||
<outlet property="contentView" destination="pcX-rB-RxJ" id="o95-Qa-6N7"/>
|
<outlet property="contentView" destination="pcX-rB-RxJ" id="o95-Qa-6N7"/>
|
||||||
<outlet property="contentWarningContainerView" destination="kU2-7l-MSy" id="Gnq-Jb-kCA"/>
|
<outlet property="contentWarningContainerView" destination="kU2-7l-MSy" id="Gnq-Jb-kCA"/>
|
||||||
<outlet property="contentWarningTextField" destination="T05-p6-vTz" id="Ivu-Ll-ByO"/>
|
<outlet property="contentWarningTextField" destination="T05-p6-vTz" id="Ivu-Ll-ByO"/>
|
||||||
|
<outlet property="inReplyToContainer" destination="2Dv-Q7-UEA" id="hfG-5j-G5R"/>
|
||||||
|
<outlet property="inReplyToLabel" destination="Y25-eP-tDE" id="9Ei-3s-dAx"/>
|
||||||
<outlet property="placeholderLabel" destination="EW3-YK-vPC" id="Rsw-Nv-TNz"/>
|
<outlet property="placeholderLabel" destination="EW3-YK-vPC" id="Rsw-Nv-TNz"/>
|
||||||
<outlet property="postProgressView" destination="Tq7-6P-hMT" id="amT-F1-JI0"/>
|
<outlet property="postProgressView" destination="Tq7-6P-hMT" id="amT-F1-JI0"/>
|
||||||
<outlet property="scrollView" destination="6Z0-Vy-hMX" id="ya0-2T-QaV"/>
|
<outlet property="scrollView" destination="6Z0-Vy-hMX" id="ya0-2T-QaV"/>
|
||||||
|
@ -33,10 +35,10 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pcX-rB-RxJ">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pcX-rB-RxJ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="342"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="371.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="bOB-hF-O9w">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="bOB-hF-O9w">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="342"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="371.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6V0-mH-Mhu">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6V0-mH-Mhu">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
|
||||||
|
@ -63,11 +65,32 @@
|
||||||
<constraint firstItem="PMB-Wa-Ht0" firstAttribute="leading" secondItem="zZ3-Gv-4P5" secondAttribute="trailing" id="sVv-tH-7eB"/>
|
<constraint firstItem="PMB-Wa-Ht0" firstAttribute="leading" secondItem="zZ3-Gv-4P5" secondAttribute="trailing" id="sVv-tH-7eB"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2Dv-Q7-UEA">
|
||||||
|
<rect key="frame" x="0.0" y="66" width="375" height="33.5"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="In reply to Display Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Y25-eP-tDE">
|
||||||
|
<rect key="frame" x="4" y="8" width="367" height="21.5"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="21.5" id="man-Xn-eVt"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="Y25-eP-tDE" secondAttribute="bottom" constant="4" id="1sZ-CX-GDU"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="Y25-eP-tDE" secondAttribute="trailing" constant="4" id="I31-Rs-QwW"/>
|
||||||
|
<constraint firstItem="Y25-eP-tDE" firstAttribute="leading" secondItem="2Dv-Q7-UEA" secondAttribute="leading" constant="4" id="kdQ-zs-u7N"/>
|
||||||
|
<constraint firstItem="Y25-eP-tDE" firstAttribute="top" secondItem="2Dv-Q7-UEA" secondAttribute="top" constant="8" id="qdC-S5-CgV"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kU2-7l-MSy">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kU2-7l-MSy">
|
||||||
<rect key="frame" x="0.0" y="66" width="375" height="46"/>
|
<rect key="frame" x="0.0" y="99.5" width="375" height="42"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Write your warning here" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="T05-p6-vTz">
|
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Write your warning here" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="T05-p6-vTz">
|
||||||
<rect key="frame" x="4" y="8" width="367" height="30"/>
|
<rect key="frame" x="4" y="4" width="367" height="30"/>
|
||||||
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="30" id="yzY-MF-Ukx"/>
|
<constraint firstAttribute="height" constant="30" id="yzY-MF-Ukx"/>
|
||||||
|
@ -80,11 +103,11 @@
|
||||||
<constraint firstAttribute="trailing" secondItem="T05-p6-vTz" secondAttribute="trailing" constant="4" id="8tG-eW-TG4"/>
|
<constraint firstAttribute="trailing" secondItem="T05-p6-vTz" secondAttribute="trailing" constant="4" id="8tG-eW-TG4"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="T05-p6-vTz" secondAttribute="bottom" constant="8" id="SUL-Hk-uvM"/>
|
<constraint firstAttribute="bottom" secondItem="T05-p6-vTz" secondAttribute="bottom" constant="8" id="SUL-Hk-uvM"/>
|
||||||
<constraint firstItem="T05-p6-vTz" firstAttribute="leading" secondItem="kU2-7l-MSy" secondAttribute="leading" constant="4" id="WGG-B2-lPC"/>
|
<constraint firstItem="T05-p6-vTz" firstAttribute="leading" secondItem="kU2-7l-MSy" secondAttribute="leading" constant="4" id="WGG-B2-lPC"/>
|
||||||
<constraint firstItem="T05-p6-vTz" firstAttribute="top" secondItem="kU2-7l-MSy" secondAttribute="top" constant="8" id="lvW-S0-4k4"/>
|
<constraint firstItem="T05-p6-vTz" firstAttribute="top" secondItem="kU2-7l-MSy" secondAttribute="top" constant="4" id="dN2-Pf-qFQ"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lhQ-ae-pe9">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lhQ-ae-pe9">
|
||||||
<rect key="frame" x="0.0" y="112" width="375" height="150"/>
|
<rect key="frame" x="0.0" y="141.5" width="375" height="150"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="9pn-0T-IHb">
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="9pn-0T-IHb">
|
||||||
<rect key="frame" x="4" y="0.0" width="367" height="150"/>
|
<rect key="frame" x="4" y="0.0" width="367" height="150"/>
|
||||||
|
@ -112,7 +135,7 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="P0F-3w-gI1">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="P0F-3w-gI1">
|
||||||
<rect key="frame" x="0.0" y="262" width="375" height="80"/>
|
<rect key="frame" x="0.0" y="291.5" width="375" height="80"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="752-dD-eAO">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="752-dD-eAO">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="80"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="80"/>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import UIKit
|
||||||
|
|
||||||
protocol DraftsTableViewControllerDelegate {
|
protocol DraftsTableViewControllerDelegate {
|
||||||
func draftSelectionCanceled()
|
func draftSelectionCanceled()
|
||||||
|
func shouldSelectDraft(_ draft: DraftsManager.Draft, completion: @escaping (Bool) -> Void)
|
||||||
func draftSelected(_ draft: DraftsManager.Draft)
|
func draftSelected(_ draft: DraftsManager.Draft)
|
||||||
func draftSelectionCompleted()
|
func draftSelectionCompleted()
|
||||||
}
|
}
|
||||||
|
@ -61,9 +62,23 @@ class DraftsTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
delegate?.draftSelected(draft(for: indexPath))
|
let draft = self.draft(for: indexPath)
|
||||||
dismiss(animated: true) {
|
func select() {
|
||||||
self.delegate?.draftSelectionCompleted()
|
delegate?.draftSelected(draft)
|
||||||
|
dismiss(animated: true) {
|
||||||
|
self.delegate?.draftSelectionCompleted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let delegate = delegate {
|
||||||
|
delegate.shouldSelectDraft(draft) { (shouldSelect) in
|
||||||
|
if shouldSelect {
|
||||||
|
select()
|
||||||
|
} else {
|
||||||
|
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
select()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue