Initial implementation Compose UI
This commit is contained in:
parent
c155f695f5
commit
99c9971fb3
|
@ -10,6 +10,8 @@
|
|||
04DACE8A212CA6B7009840C4 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE89212CA6B7009840C4 /* Timeline.swift */; };
|
||||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */; };
|
||||
04DACE8E212CC7CC009840C4 /* AvatarCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8D212CC7CC009840C4 /* AvatarCache.swift */; };
|
||||
D6333B372137838300CE884A /* AttributedString+Trim.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Trim.swift */; };
|
||||
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B762138D94E00CE884A /* ComposeMediaView.swift */; };
|
||||
D64A0CD32132153900640E3B /* HTMLContentLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A0CD22132153900640E3B /* HTMLContentLabel.swift */; };
|
||||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; };
|
||||
D64D0AAF2128D954005A6F37 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */; };
|
||||
|
@ -22,6 +24,10 @@
|
|||
D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */; };
|
||||
D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */; };
|
||||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; };
|
||||
D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626E213632A000C9CBA2 /* Compose.storyboard */; };
|
||||
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; };
|
||||
D66362732136FFC600C9CBA2 /* UITextView+Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */; };
|
||||
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; };
|
||||
D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; };
|
||||
D667E5E3213499F70057A976 /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E2213499F70057A976 /* Profile.storyboard */; };
|
||||
D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */; };
|
||||
|
@ -84,6 +90,8 @@
|
|||
04DACE89212CA6B7009840C4 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; };
|
||||
04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = "<group>"; };
|
||||
04DACE8D212CC7CC009840C4 /* AvatarCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarCache.swift; sourceTree = "<group>"; };
|
||||
D6333B362137838300CE884A /* AttributedString+Trim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+Trim.swift"; sourceTree = "<group>"; };
|
||||
D6333B762138D94E00CE884A /* ComposeMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeMediaView.swift; sourceTree = "<group>"; };
|
||||
D64A0CD22132153900640E3B /* HTMLContentLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTMLContentLabel.swift; sourceTree = "<group>"; };
|
||||
D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; };
|
||||
D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = "<group>"; };
|
||||
|
@ -97,6 +105,10 @@
|
|||
D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesAdaptive.swift; sourceTree = "<group>"; };
|
||||
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = "<group>"; };
|
||||
D663626D213629B300C9CBA2 /* MyPlayground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = MyPlayground.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
D663626E213632A000C9CBA2 /* Compose.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Compose.storyboard; sourceTree = "<group>"; };
|
||||
D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; };
|
||||
D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Placeholder.swift"; sourceTree = "<group>"; };
|
||||
D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visibility+Helpers.swift"; sourceTree = "<group>"; };
|
||||
D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D667E5E2213499F70057A976 /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = "<group>"; };
|
||||
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -170,6 +182,9 @@
|
|||
D667E5F02134D5050057A976 /* UIViewController+StatusTableViewCellDelegate.swift */,
|
||||
D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */,
|
||||
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */,
|
||||
D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */,
|
||||
D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */,
|
||||
D6333B362137838300CE884A /* AttributedString+Trim.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
@ -185,6 +200,7 @@
|
|||
D667E5EA21349EF80057A976 /* ProfileHeaderTableViewCell.swift */,
|
||||
D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */,
|
||||
D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */,
|
||||
D6333B762138D94E00CE884A /* ComposeMediaView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -259,6 +275,7 @@
|
|||
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */,
|
||||
D667E5F42135BCD50057A976 /* ConversationViewController.swift */,
|
||||
D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */,
|
||||
D66362702136338600C9CBA2 /* ComposeViewController.swift */,
|
||||
);
|
||||
path = "View Controllers";
|
||||
sourceTree = "<group>";
|
||||
|
@ -272,6 +289,7 @@
|
|||
D667E5E2213499F70057A976 /* Profile.storyboard */,
|
||||
D667E5F22135BC260057A976 /* Conversation.storyboard */,
|
||||
D663626521360DD700C9CBA2 /* Preferences.storyboard */,
|
||||
D663626E213632A000C9CBA2 /* Compose.storyboard */,
|
||||
);
|
||||
path = Storyboards;
|
||||
sourceTree = "<group>";
|
||||
|
@ -396,6 +414,7 @@
|
|||
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */,
|
||||
D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */,
|
||||
D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */,
|
||||
D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */,
|
||||
D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */,
|
||||
D667E5E3213499F70057A976 /* Profile.storyboard in Resources */,
|
||||
D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */,
|
||||
|
@ -428,16 +447,21 @@
|
|||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
||||
D667E5F52135BCD50057A976 /* ConversationViewController.swift in Sources */,
|
||||
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */,
|
||||
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */,
|
||||
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */,
|
||||
04DACE8E212CC7CC009840C4 /* AvatarCache.swift in Sources */,
|
||||
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */,
|
||||
D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */,
|
||||
D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */,
|
||||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */,
|
||||
D663626221360B1900C9CBA2 /* Preferences.swift in Sources */,
|
||||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */,
|
||||
D6333B372137838300CE884A /* AttributedString+Trim.swift in Sources */,
|
||||
D667E5EF2134C39F0057A976 /* StatusContentLabel.swift in Sources */,
|
||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */,
|
||||
D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */,
|
||||
D66362732136FFC600C9CBA2 /* UITextView+Placeholder.swift in Sources */,
|
||||
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */,
|
||||
D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */,
|
||||
D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */,
|
||||
D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */,
|
||||
|
|
|
@ -18,6 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
|
||||
if LocalData.shared.onboardingComplete {
|
||||
MastodonController.shared.createClient()
|
||||
MastodonController.shared.getOwnAccount()
|
||||
} else {
|
||||
showOnboarding()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Remove.pdf",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
%PDF-1.5
|
||||
%µí®û
|
||||
3 0 obj
|
||||
<< /Length 4 0 R
|
||||
/Filter /FlateDecode
|
||||
>>
|
||||
stream
|
||||
xœePËN1¼û+æ0Žóò^{©„Ä¡\´¨=ý}œlV° +rÆž;¹’ Åç ÷¯‚Ó´xÚ£rÆÍÛ~Þéù‚7JxÄÕMu×’ —J1̪…Í"’°—pÁÀE8]Ó–4Ð&D®yUôûàÏì‘~ú}^¥Ôá²ñcxþ·÷‡ñþ3Á¼ªÈ•UÔ›¹”r–Š”ÈqòU”«NŽ³±XA¨œ:>Ó_‡c«$K]cæ×h¶îYÂâ™Ë¢èØgV›º§ï9<7G:Ð7~s[O
|
||||
endstream
|
||||
endobj
|
||||
4 0 obj
|
||||
226
|
||||
endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/ExtGState <<
|
||||
/a0 << /CA 1 /ca 1 >>
|
||||
>>
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<< /Type /Page
|
||||
/Parent 1 0 R
|
||||
/MediaBox [ 0 0 80.631668 80.631668 ]
|
||||
/Contents 3 0 R
|
||||
/Group <<
|
||||
/Type /Group
|
||||
/S /Transparency
|
||||
/I true
|
||||
/CS /DeviceRGB
|
||||
>>
|
||||
/Resources 2 0 R
|
||||
>>
|
||||
endobj
|
||||
1 0 obj
|
||||
<< /Type /Pages
|
||||
/Kids [ 5 0 R ]
|
||||
/Count 1
|
||||
>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<< /Creator (cairo 1.14.8 (http://cairographics.org))
|
||||
/Producer (cairo 1.14.8 (http://cairographics.org))
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<< /Type /Catalog
|
||||
/Pages 1 0 R
|
||||
>>
|
||||
endobj
|
||||
xref
|
||||
0 8
|
||||
0000000000 65535 f
|
||||
0000000638 00000 n
|
||||
0000000340 00000 n
|
||||
0000000015 00000 n
|
||||
0000000318 00000 n
|
||||
0000000412 00000 n
|
||||
0000000703 00000 n
|
||||
0000000830 00000 n
|
||||
trailer
|
||||
<< /Size 8
|
||||
/Root 7 0 R
|
||||
/Info 6 0 R
|
||||
>>
|
||||
startxref
|
||||
882
|
||||
%%EOF
|
|
@ -15,6 +15,8 @@ class MastodonController {
|
|||
|
||||
var client: Client!
|
||||
|
||||
var account: Account!
|
||||
|
||||
private init() {
|
||||
}
|
||||
|
||||
|
@ -55,4 +57,12 @@ class MastodonController {
|
|||
}
|
||||
}
|
||||
|
||||
func getOwnAccount() {
|
||||
let req = Accounts.currentUser()
|
||||
client.run(req) { result in
|
||||
guard case let .success(account, _) = result else { fatalError() }
|
||||
self.account = account
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// PlaceholderTextView.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 8/29/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
// Source: https://finnwea.com/blog/adding-placeholders-to-uitextviews-in-swift/
|
||||
extension UITextView: UITextViewDelegate {
|
||||
|
||||
override open var bounds: CGRect {
|
||||
didSet {
|
||||
resizePlaceholder()
|
||||
}
|
||||
}
|
||||
|
||||
var placeholder: String? {
|
||||
get {
|
||||
return (viewWithTag(100) as? UILabel)?.text
|
||||
}
|
||||
set {
|
||||
if let placeholderLabel = viewWithTag(100) as? UILabel {
|
||||
placeholderLabel.text = newValue
|
||||
placeholderLabel.sizeToFit()
|
||||
} else {
|
||||
guard let newValue = newValue else { return }
|
||||
addPlaceholder(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func textViewDidChange(_ textView: UITextView) {
|
||||
if let placeholderLabel = viewWithTag(100) as? UILabel {
|
||||
placeholderLabel.isHidden = !text.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
private func resizePlaceholder() {
|
||||
guard let placeholderLabel = viewWithTag(100) as? UILabel else { fatalError() }
|
||||
let labelX = textContainer.lineFragmentPadding
|
||||
let labelY = textContainerInset.top
|
||||
let labelWidth = frame.width - (labelX * 2)
|
||||
let labelHeight = placeholderLabel.frame.height
|
||||
placeholderLabel.frame = CGRect(x: labelX, y: labelY, width: labelWidth, height: labelHeight)
|
||||
}
|
||||
|
||||
private func addPlaceholder(_ placeholderText: String) {
|
||||
let placeholderLabel = UILabel()
|
||||
|
||||
placeholderLabel.text = placeholderText
|
||||
placeholderLabel.sizeToFit()
|
||||
placeholderLabel.font = font
|
||||
placeholderLabel.textColor = .lightGray
|
||||
placeholderLabel.tag = 100
|
||||
|
||||
placeholderLabel.isHighlighted = !text.isEmpty
|
||||
|
||||
addSubview(placeholderLabel)
|
||||
resizePlaceholder()
|
||||
delegate = self
|
||||
|
||||
}
|
||||
}
|
|
@ -53,4 +53,9 @@ extension UIViewController: StatusTableViewCellDelegate {
|
|||
navigationController.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
func reply(to status: Status) {
|
||||
let vc = ComposeViewController.create(inReplyTo: status)
|
||||
present(vc, animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// Visibility+String.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 8/29/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import MastodonKit
|
||||
|
||||
extension Visibility {
|
||||
|
||||
static var allCases: [Visibility] {
|
||||
return [.public, .unlisted, .private, .direct]
|
||||
}
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .public:
|
||||
return "Public"
|
||||
case .unlisted:
|
||||
return "Unlisted"
|
||||
case .private:
|
||||
return "Private"
|
||||
case .direct:
|
||||
return "Direct"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>To post photos from the camera.</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>To post photos from the photo library.</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MastodonKit
|
||||
|
||||
class Preferences: Codable {
|
||||
|
||||
|
@ -36,4 +37,6 @@ class Preferences: Codable {
|
|||
|
||||
var hideCustomEmojiInUsernames = false
|
||||
|
||||
var defaultPostVisibility = Visibility.public
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="8eV-YC-Spl">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.9"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Compose-->
|
||||
<scene sceneID="Dve-lH-JJK">
|
||||
<objects>
|
||||
<viewController id="svD-Ql-HGm" customClass="ComposeViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="qto-r6-ocp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="L3H-aB-fGr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="WID-nQ-ZzS">
|
||||
<rect key="frame" x="16" y="16" width="343" height="735"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l0G-YS-00D">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="128"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="2fn-pv-lwV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="L4b-xJ-V5E"/>
|
||||
<constraint firstAttribute="width" constant="50" id="V0U-ps-ejP"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kBr-of-4cF">
|
||||
<rect key="frame" x="58" y="0.0" width="105" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="neM-1F-PcJ">
|
||||
<rect key="frame" x="171" y="0.0" width="172" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WcY-cJ-FqF" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="58" y="28.5" width="285" height="99.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="2fn-pv-lwV" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="17U-sX-oMw"/>
|
||||
<constraint firstAttribute="bottom" secondItem="WcY-cJ-FqF" secondAttribute="bottom" id="EVN-o1-tfI"/>
|
||||
<constraint firstItem="neM-1F-PcJ" firstAttribute="leading" secondItem="kBr-of-4cF" secondAttribute="trailing" constant="8" id="Iy1-we-N0r"/>
|
||||
<constraint firstAttribute="trailing" secondItem="neM-1F-PcJ" secondAttribute="trailing" id="XK2-sV-Cgu"/>
|
||||
<constraint firstItem="WcY-cJ-FqF" firstAttribute="leading" secondItem="2fn-pv-lwV" secondAttribute="trailing" constant="8" id="ZuW-k7-y14"/>
|
||||
<constraint firstItem="WcY-cJ-FqF" firstAttribute="top" secondItem="kBr-of-4cF" secondAttribute="bottom" constant="8" id="bwQ-WL-uN8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="WcY-cJ-FqF" secondAttribute="trailing" id="jUB-n1-YWr"/>
|
||||
<constraint firstItem="neM-1F-PcJ" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="mam-bN-10G"/>
|
||||
<constraint firstItem="kBr-of-4cF" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="vgj-G0-dv2"/>
|
||||
<constraint firstItem="kBr-of-4cF" firstAttribute="leading" secondItem="2fn-pv-lwV" secondAttribute="trailing" constant="8" id="yZV-4x-7s6"/>
|
||||
<constraint firstItem="2fn-pv-lwV" firstAttribute="leading" secondItem="l0G-YS-00D" secondAttribute="leading" id="zdv-5N-Xyl"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="bGo-tx-r56">
|
||||
<rect key="frame" x="0.0" y="136" width="343" height="599"/>
|
||||
<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="NGI-fk-d7F">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="gQU-rc-mM7">
|
||||
<rect key="frame" x="0.0" y="26.5" width="343" height="200"/>
|
||||
<color key="backgroundColor" red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="200" id="ugS-rN-LrW"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="cfA-uo-q9g">
|
||||
<rect key="frame" x="0.0" y="232.5" width="343" height="30"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wW4-Zd-GH4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="42" height="30"/>
|
||||
<state key="normal" title="Media"/>
|
||||
<connections>
|
||||
<action selector="mediaPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="0pB-L2-VZa"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EOO-If-BeL">
|
||||
<rect key="frame" x="50" y="0.0" width="30" height="30"/>
|
||||
<state key="normal" title="CW"/>
|
||||
<connections>
|
||||
<action selector="contentWarningPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="O1a-3w-Ofr"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="caP-6L-HWj">
|
||||
<rect key="frame" x="88" y="0.0" width="42" height="30"/>
|
||||
<state key="normal" title="Public"/>
|
||||
<connections>
|
||||
<action selector="visibilityPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="aeI-Wi-7Mz"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wg4-nL-Q7B">
|
||||
<rect key="frame" x="138" y="0.0" width="205" height="30"/>
|
||||
<state key="normal" title="Post"/>
|
||||
<connections>
|
||||
<action selector="postPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="HqO-kb-qcz"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<textField hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Content Warning" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Rbm-SO-Cpp">
|
||||
<rect key="frame" x="0.0" y="265.5" width="343" height="0.0"/>
|
||||
<nil key="textColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" returnKeyType="done"/>
|
||||
</textField>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="gcH-tf-prn">
|
||||
<rect key="frame" x="0.0" y="268.5" width="343" height="100"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="100" id="0BL-1Y-g90"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="VuB-eX-IiL">
|
||||
<rect key="frame" x="0.0" y="374.5" width="343" height="224.5"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="WID-nQ-ZzS" secondAttribute="trailing" constant="16" id="0Sy-jt-Ddv"/>
|
||||
<constraint firstItem="bGo-tx-r56" firstAttribute="height" secondItem="L3H-aB-fGr" secondAttribute="height" constant="-68" id="5Xh-ao-jAN"/>
|
||||
<constraint firstItem="WID-nQ-ZzS" firstAttribute="leading" secondItem="L3H-aB-fGr" secondAttribute="leading" constant="16" id="8Aw-l2-092"/>
|
||||
<constraint firstItem="WID-nQ-ZzS" firstAttribute="top" secondItem="L3H-aB-fGr" secondAttribute="top" constant="16" id="CYg-ft-CAr"/>
|
||||
<constraint firstAttribute="bottom" secondItem="WID-nQ-ZzS" secondAttribute="bottom" id="yTD-d9-Cr8"/>
|
||||
</constraints>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="L3H-aB-fGr" firstAttribute="leading" secondItem="qto-r6-ocp" secondAttribute="leading" id="01l-qs-Ff4"/>
|
||||
<constraint firstItem="L3H-aB-fGr" firstAttribute="top" secondItem="qto-r6-ocp" secondAttribute="topMargin" constant="-64" id="7BB-7k-gaN"/>
|
||||
<constraint firstItem="WID-nQ-ZzS" firstAttribute="width" secondItem="qto-r6-ocp" secondAttribute="width" constant="-32" id="Fer-8I-o1H"/>
|
||||
<constraint firstAttribute="trailing" secondItem="L3H-aB-fGr" secondAttribute="trailing" id="NWJ-dh-7ED"/>
|
||||
<constraint firstItem="7ws-AM-scc" firstAttribute="bottom" secondItem="L3H-aB-fGr" secondAttribute="bottom" id="uZs-Y8-hGM"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="7ws-AM-scc"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Compose" id="WVz-mo-nCC">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="94u-El-jk4">
|
||||
<connections>
|
||||
<segue destination="XCi-Fs-398" kind="unwind" identifier="cancel" unwindAction="unwindToTabBarControllerWithSegue:" id="R9N-eg-Lp6"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="contentWarningTextField" destination="Rbm-SO-Cpp" id="d1F-yi-CnV"/>
|
||||
<outlet property="inReplyToAvatarImageView" destination="2fn-pv-lwV" id="SMy-L1-bI1"/>
|
||||
<outlet property="inReplyToContainerView" destination="l0G-YS-00D" id="XO0-HW-WVf"/>
|
||||
<outlet property="inReplyToContentLabel" destination="WcY-cJ-FqF" id="JNr-hO-QPO"/>
|
||||
<outlet property="inReplyToDisplayNameLabel" destination="kBr-of-4cF" id="bWk-5w-vJb"/>
|
||||
<outlet property="inReplyToLabel" destination="NGI-fk-d7F" id="S59-D5-9bF"/>
|
||||
<outlet property="inReplyToUsernameLabel" destination="neM-1F-PcJ" id="Lej-ut-yp9"/>
|
||||
<outlet property="mediaStackView" destination="gcH-tf-prn" id="oM2-hc-rXY"/>
|
||||
<outlet property="paddingView" destination="VuB-eX-IiL" id="wDo-4O-g30"/>
|
||||
<outlet property="scrollView" destination="L3H-aB-fGr" id="kbS-H5-K2I"/>
|
||||
<outlet property="statusTextView" destination="gQU-rc-mM7" id="FVL-nk-159"/>
|
||||
<outlet property="visibilityButton" destination="caP-6L-HWj" id="89p-Bl-cRH"/>
|
||||
<segue destination="XCi-Fs-398" kind="unwind" identifier="postComplete" unwindAction="unwindToTabBarControllerWithSegue:" id="00m-ok-xPA"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="jeI-ty-LsU" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="XCi-Fs-398" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1048.8" y="-157.87106446776613"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="RHQ-fP-dlc">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="8eV-YC-Spl" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="PYB-mm-ur8">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="svD-Ql-HGm" kind="relationship" relationship="rootViewController" id="WUM-0u-sCZ"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="RLe-aq-Yb1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="109.59999999999999" y="-157.87106446776613"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -21,8 +21,15 @@
|
|||
<outlet property="delegate" destination="HMn-Wn-5Ab" id="PbX-SY-1Qw"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" id="bvr-ex-deZ"/>
|
||||
<navigationItem key="navigationItem" id="bvr-ex-deZ">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="compose" id="4lI-Md-Vmw">
|
||||
<connections>
|
||||
<action selector="composePressed:" destination="HMn-Wn-5Ab" id="TRT-Dp-Rwx"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="aAC-id-7YO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<connections>
|
||||
<action selector="refreshStatuses:" destination="HMn-Wn-5Ab" eventType="valueChanged" id="uPt-pK-1iL"/>
|
||||
|
|
|
@ -21,7 +21,13 @@
|
|||
<outlet property="delegate" destination="6nb-nb-cMm" id="Dio-U3-a5Z"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" id="SQS-FM-ReS"/>
|
||||
<navigationItem key="navigationItem" id="SQS-FM-ReS">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="compose" id="nVG-dM-Pvp">
|
||||
<connections>
|
||||
<segue destination="Xq5-zT-4uE" kind="presentation" id="2rg-sr-zDQ"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="K3b-fx-67z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
|
||||
|
@ -35,6 +41,14 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="800.79999999999995" y="-90.404797601199405"/>
|
||||
</scene>
|
||||
<!--Compose-->
|
||||
<scene sceneID="bcB-Kb-Axl">
|
||||
<objects>
|
||||
<viewControllerPlaceholder storyboardName="Compose" id="Xq5-zT-4uE" sceneMemberID="viewController"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="T2a-NG-JV4" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1410" y="-359"/>
|
||||
</scene>
|
||||
<!--Item-->
|
||||
<scene sceneID="yNQ-ej-ymp">
|
||||
<objects>
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
//
|
||||
// ComposeViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 8/28/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MastodonKit
|
||||
|
||||
class ComposeViewController: UIViewController {
|
||||
|
||||
static func create(inReplyTo: Status? = nil, mentioning: Account? = nil) -> UIViewController {
|
||||
guard let navigationController = UIStoryboard(name: "Compose", bundle: nil).instantiateInitialViewController() as? UINavigationController,
|
||||
let composeVC = navigationController.topViewController as? ComposeViewController else { fatalError() }
|
||||
composeVC.inReplyTo = inReplyTo
|
||||
composeVC.mentioning = mentioning
|
||||
return navigationController
|
||||
}
|
||||
|
||||
@IBOutlet weak var scrollView: UIScrollView!
|
||||
@IBOutlet weak var inReplyToContainerView: UIView!
|
||||
@IBOutlet weak var inReplyToAvatarImageView: UIImageView!
|
||||
@IBOutlet weak var inReplyToDisplayNameLabel: UILabel!
|
||||
@IBOutlet weak var inReplyToUsernameLabel: UILabel!
|
||||
@IBOutlet weak var inReplyToContentLabel: StatusContentLabel!
|
||||
@IBOutlet weak var inReplyToLabel: UILabel!
|
||||
@IBOutlet weak var statusTextView: UITextView!
|
||||
@IBOutlet weak var visibilityButton: UIButton!
|
||||
@IBOutlet weak var contentWarningTextField: UITextField!
|
||||
@IBOutlet weak var mediaStackView: UIStackView!
|
||||
@IBOutlet weak var paddingView: UIView!
|
||||
|
||||
var scrolled = false
|
||||
|
||||
var inReplyTo: Status?
|
||||
var mentioning: Account?
|
||||
|
||||
var contentWarning = false
|
||||
var visibility = Preferences.shared.defaultPostVisibility
|
||||
|
||||
var status: Status?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
statusTextView.placeholder = "What is on your mind?"
|
||||
statusTextView.layer.cornerRadius = 5
|
||||
statusTextView.layer.masksToBounds = true
|
||||
visibilityButton.setTitle(visibility.displayName, for: .normal)
|
||||
contentWarningTextField.delegate = self
|
||||
|
||||
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 30))
|
||||
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(keyboardDoneButtonPressed))
|
||||
toolbar.setItems([flexSpace, done], animated: false)
|
||||
toolbar.sizeToFit()
|
||||
statusTextView.inputAccessoryView = toolbar
|
||||
|
||||
if let inReplyTo = inReplyTo {
|
||||
inReplyToDisplayNameLabel.text = inReplyTo.account.realDisplayName
|
||||
inReplyToUsernameLabel.text = "@\(inReplyTo.account.username)"
|
||||
inReplyToContentLabel.status = inReplyTo
|
||||
inReplyToAvatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: inReplyToAvatarImageView)
|
||||
inReplyToAvatarImageView.layer.masksToBounds = true
|
||||
inReplyToAvatarImageView.image = nil
|
||||
if let url = URL(string: inReplyTo.account.avatar) {
|
||||
AvatarCache.shared.get(url) { image in
|
||||
DispatchQueue.main.async {
|
||||
self.inReplyToAvatarImageView.image = image
|
||||
}
|
||||
}
|
||||
}
|
||||
inReplyToLabel.text = "In reply to \(inReplyTo.account.realDisplayName)"
|
||||
if inReplyTo.account != MastodonController.shared.account {
|
||||
statusTextView.text = "@\(inReplyTo.account.acct) "
|
||||
}
|
||||
statusTextView.text += inReplyTo.mentions.filter({ $0.id != MastodonController.shared.account.id }).map({ "@\($0.acct) " }).joined()
|
||||
statusTextView.textViewDidChange(statusTextView)
|
||||
} else {
|
||||
inReplyToLabel.isHidden = true
|
||||
inReplyToContainerView.isHidden = true
|
||||
}
|
||||
|
||||
if let mentioning = mentioning {
|
||||
statusTextView.text += "@\(mentioning.acct) "
|
||||
statusTextView.textViewDidChange(statusTextView)
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
if inReplyTo != nil && !scrolled {
|
||||
scrollView.contentOffset = CGPoint(x: 0, y: inReplyToContainerView.bounds.height - 44)
|
||||
scrolled = true
|
||||
}
|
||||
}
|
||||
|
||||
func addMedia(for image: UIImage) {
|
||||
let mediaView = ComposeMediaView(image: image)
|
||||
mediaStackView.addArrangedSubview(mediaView)
|
||||
}
|
||||
|
||||
// MARK: - Navigation
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
statusTextView.resignFirstResponder()
|
||||
contentWarningTextField.resignFirstResponder()
|
||||
|
||||
if segue.identifier == "postComplete" {
|
||||
guard let status = status else { fatalError("postComplete segue can't occur without Status") }
|
||||
guard let dest = segue.destination as? MainTabBarViewController,
|
||||
let navController = dest.selectedViewController as? UINavigationController,
|
||||
let topVC = navController.topViewController else { return }
|
||||
topVC.selected(status: status)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Interaction
|
||||
|
||||
@IBAction func visibilityPressed(_ sender: Any) {
|
||||
let alertController = UIAlertController(title: "Post Visibility", message: nil, preferredStyle: .actionSheet)
|
||||
for visibility in Visibility.allCases {
|
||||
let action = UIAlertAction(title: visibility.displayName, style: .default, handler: { _ in
|
||||
self.visibility = visibility
|
||||
UIView.performWithoutAnimation {
|
||||
self.visibilityButton.setTitle(visibility.displayName, for: .normal)
|
||||
self.visibilityButton.layoutIfNeeded()
|
||||
}
|
||||
})
|
||||
if visibility == self.visibility {
|
||||
action.setValue(true, forKey: "checked")
|
||||
}
|
||||
alertController.addAction(action)
|
||||
}
|
||||
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
present(alertController, animated: true)
|
||||
}
|
||||
|
||||
@IBAction func contentWarningPressed(_ sender: Any) {
|
||||
contentWarning = !contentWarning
|
||||
contentWarningTextField.isHidden = !contentWarning
|
||||
}
|
||||
|
||||
@IBAction func mediaPressed(_ sender: Any) {
|
||||
let imagePicker = UIImagePickerController()
|
||||
imagePicker.delegate = self
|
||||
|
||||
let alertController = UIAlertController(title: "Choose Image Source", message: nil, preferredStyle: .actionSheet)
|
||||
if UIImagePickerController.isSourceTypeAvailable(.camera) {
|
||||
alertController.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
|
||||
imagePicker.sourceType = .camera
|
||||
self.present(imagePicker, animated: true)
|
||||
}))
|
||||
}
|
||||
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
|
||||
alertController.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { __ in
|
||||
imagePicker.sourceType = .photoLibrary
|
||||
self.present(imagePicker, animated: true)
|
||||
}))
|
||||
}
|
||||
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
present(alertController, animated: true)
|
||||
}
|
||||
|
||||
@IBAction func postPressed(_ sender: Any) {
|
||||
guard let text = statusTextView.text,
|
||||
!text.isEmpty else { return }
|
||||
|
||||
let inReplyToID = inReplyTo?.id
|
||||
|
||||
let contentWarning: String?
|
||||
if self.contentWarning,
|
||||
let text = contentWarningTextField.text,
|
||||
!text.isEmpty {
|
||||
contentWarning = text
|
||||
} else {
|
||||
contentWarning = nil
|
||||
}
|
||||
let sensitive = contentWarning != nil
|
||||
|
||||
let visibility = self.visibility
|
||||
|
||||
var attachments: [Attachment?] = []
|
||||
let group = DispatchGroup()
|
||||
for view in mediaStackView.arrangedSubviews {
|
||||
guard let imageView = view as? UIImageView,
|
||||
let image = imageView.image,
|
||||
let data = image.pngData() else { continue }
|
||||
let index = attachments.count
|
||||
attachments.append(nil)
|
||||
group.enter()
|
||||
let req = Media.upload(media: .png(data))
|
||||
MastodonController.shared.client.run(req) { result in
|
||||
guard case let .success(attachment, _) = result else { fatalError() }
|
||||
attachments[index] = attachment
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: .main) {
|
||||
let mediaIDs = attachments.map { $0!.id }
|
||||
|
||||
let req = Statuses.create(status: text,
|
||||
replyToID: inReplyToID,
|
||||
mediaIDs: mediaIDs,
|
||||
sensitive: sensitive,
|
||||
spoilerText: contentWarning,
|
||||
visibility: visibility)
|
||||
|
||||
MastodonController.shared.client.run(req) { result in
|
||||
guard case let .success(status, _) = result else { fatalError() }
|
||||
self.status = status
|
||||
DispatchQueue.main.async {
|
||||
self.performSegue(withIdentifier: "postComplete", sender: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func imagePressed(_ gesture: UITapGestureRecognizer) {
|
||||
gesture.view!.superview!.removeFromSuperview()
|
||||
}
|
||||
|
||||
@objc func keyboardDoneButtonPressed() {
|
||||
statusTextView.endEditing(false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ComposeViewController: UITextFieldDelegate {
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.endEditing(false)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension ComposeViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
||||
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
||||
if let selectedImage = info[.originalImage] as? UIImage {
|
||||
addMedia(for: selectedImage)
|
||||
dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,4 +32,7 @@ class MainTabBarViewController: UITabBarController {
|
|||
}
|
||||
*/
|
||||
|
||||
@IBAction func unwindToTabBarController(segue: UIStoryboardSegue) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive {
|
|||
|
||||
updateUIForPreferences()
|
||||
|
||||
|
||||
|
||||
MastodonController.shared.client.run(request()) { result in
|
||||
guard case let .success(statuses, pagination) = result else { fatalError() }
|
||||
self.statuses = statuses
|
||||
|
@ -70,6 +72,11 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive {
|
|||
navigationItem.title = account.realDisplayName
|
||||
}
|
||||
|
||||
func sendMessageMentioning() {
|
||||
let vc = ComposeViewController.create(mentioning: account)
|
||||
present(vc, animated: true)
|
||||
}
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
|
@ -146,6 +153,11 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func composePressed(_ sender: Any) {
|
||||
sendMessageMentioning()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
|
||||
|
@ -161,7 +173,7 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
|
|||
self.present(vc, animated: true)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Send Message...", style: .default, handler: { _ in
|
||||
print("send message to @\(self.account.acct)")
|
||||
self.sendMessageMentioning()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
present(alert, animated: true)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// ComposeAttachmentView.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 8/30/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ComposeMediaView: UIImageView {
|
||||
|
||||
var remove: UIImageView
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
return nil
|
||||
}
|
||||
|
||||
init(image: UIImage) {
|
||||
remove = UIImageView(image: UIImage(named: "Remove"))
|
||||
|
||||
super.init(image: image)
|
||||
|
||||
contentMode = .scaleAspectFill
|
||||
layer.cornerRadius = 5
|
||||
layer.masksToBounds = true
|
||||
isUserInteractionEnabled = true
|
||||
|
||||
remove.isUserInteractionEnabled = true
|
||||
remove.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(removePressed)))
|
||||
remove.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(remove)
|
||||
|
||||
remove.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||
remove.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||
remove.topAnchor.constraint(equalTo: topAnchor, constant: 5).isActive = true
|
||||
remove.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5).isActive = true
|
||||
}
|
||||
|
||||
@objc func removePressed() {
|
||||
removeFromSuperview()
|
||||
}
|
||||
|
||||
}
|
|
@ -77,6 +77,10 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive
|
|||
delegate?.selected(account: account)
|
||||
}
|
||||
|
||||
@IBAction func replyPressed(_ sender: Any) {
|
||||
delegate?.reply(to: status)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ConversationMainStatusTableViewCell: HTMLContentLabelDelegate {
|
||||
|
|
|
@ -15,46 +15,75 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="mB9-HO-1vf">
|
||||
<rect key="frame" x="16" y="8" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="XPF-UL-68q"/>
|
||||
<constraint firstAttribute="width" constant="50" id="Yxp-Vr-dfl"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lZY-2e-17d">
|
||||
<rect key="frame" x="74" y="8" width="285" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="24"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SWg-Ka-QyP">
|
||||
<rect key="frame" x="74" y="37.5" width="285" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TgY-hs-Klo" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="66" width="343" height="126"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="GuG-Qd-B8I">
|
||||
<rect key="frame" x="16" y="8" width="343" height="184"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Cnd-Fj-B7l">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="146"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="mB9-HO-1vf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="XPF-UL-68q"/>
|
||||
<constraint firstAttribute="width" constant="50" id="Yxp-Vr-dfl"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lZY-2e-17d">
|
||||
<rect key="frame" x="58" y="0.0" width="285" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="24"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SWg-Ka-QyP">
|
||||
<rect key="frame" x="58" y="29" width="285" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TgY-hs-Klo" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="58" width="343" height="88"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="TgY-hs-Klo" firstAttribute="leading" secondItem="Cnd-Fj-B7l" secondAttribute="leading" id="2zu-G9-fMv"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SWg-Ka-QyP" secondAttribute="trailing" id="4g6-BT-eW4"/>
|
||||
<constraint firstAttribute="bottom" secondItem="TgY-hs-Klo" secondAttribute="bottom" id="5Og-Pd-Vck"/>
|
||||
<constraint firstItem="lZY-2e-17d" firstAttribute="top" secondItem="Cnd-Fj-B7l" secondAttribute="top" id="8fU-y9-K5Z"/>
|
||||
<constraint firstItem="lZY-2e-17d" firstAttribute="leading" secondItem="mB9-HO-1vf" secondAttribute="trailing" constant="8" id="Aqj-co-Szp"/>
|
||||
<constraint firstItem="mB9-HO-1vf" firstAttribute="top" secondItem="Cnd-Fj-B7l" secondAttribute="top" id="R7P-rD-Gbm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TgY-hs-Klo" secondAttribute="trailing" id="SOE-Q5-IWd"/>
|
||||
<constraint firstItem="mB9-HO-1vf" firstAttribute="leading" secondItem="Cnd-Fj-B7l" secondAttribute="leading" id="bxq-Fs-1aH"/>
|
||||
<constraint firstItem="SWg-Ka-QyP" firstAttribute="leading" secondItem="mB9-HO-1vf" secondAttribute="trailing" constant="8" id="e45-gE-myI"/>
|
||||
<constraint firstItem="TgY-hs-Klo" firstAttribute="top" secondItem="mB9-HO-1vf" secondAttribute="bottom" constant="8" id="l6y-Rr-Nmc"/>
|
||||
<constraint firstItem="SWg-Ka-QyP" firstAttribute="top" secondItem="lZY-2e-17d" secondAttribute="bottom" id="lvX-1b-8cN"/>
|
||||
<constraint firstAttribute="trailing" secondItem="lZY-2e-17d" secondAttribute="trailing" id="qcG-N7-OIv"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="3Bg-XP-d13">
|
||||
<rect key="frame" x="0.0" y="154" width="343" height="30"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2cc-lE-AdG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="30"/>
|
||||
<state key="normal" title="Reply"/>
|
||||
<connections>
|
||||
<action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="hsh-gx-Swo"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="TgY-hs-Klo" secondAttribute="trailing" constant="16" id="E3q-sb-FJE"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="lZY-2e-17d" secondAttribute="trailing" constant="16" id="ESw-bn-lfh"/>
|
||||
<constraint firstItem="lZY-2e-17d" firstAttribute="leading" secondItem="mB9-HO-1vf" secondAttribute="trailing" constant="8" id="Egk-Kr-F8T"/>
|
||||
<constraint firstItem="TgY-hs-Klo" firstAttribute="top" secondItem="mB9-HO-1vf" secondAttribute="bottom" constant="8" id="U7U-WR-0eG"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="SWg-Ka-QyP" secondAttribute="trailing" constant="16" id="YaX-Rf-6px"/>
|
||||
<constraint firstItem="TgY-hs-Klo" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="Zn0-1F-UT0"/>
|
||||
<constraint firstItem="mB9-HO-1vf" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="8" id="avn-ir-MvB"/>
|
||||
<constraint firstItem="SWg-Ka-QyP" firstAttribute="leading" secondItem="mB9-HO-1vf" secondAttribute="trailing" constant="8" id="bAC-TW-LbN"/>
|
||||
<constraint firstItem="mB9-HO-1vf" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="bqf-Es-GfP"/>
|
||||
<constraint firstItem="SWg-Ka-QyP" firstAttribute="bottom" secondItem="mB9-HO-1vf" secondAttribute="bottom" id="c2R-gl-ybl"/>
|
||||
<constraint firstItem="lZY-2e-17d" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="8" id="uWl-Wj-Zvr"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="TgY-hs-Klo" secondAttribute="bottom" constant="8" id="zlq-nS-Uff"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="GuG-Qd-B8I" secondAttribute="bottom" constant="8" id="2F3-0f-0tC"/>
|
||||
<constraint firstItem="GuG-Qd-B8I" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="PFH-TI-ZQ9"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="GuG-Qd-B8I" secondAttribute="trailing" constant="16" id="WpU-W0-YkL"/>
|
||||
<constraint firstItem="GuG-Qd-B8I" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="8" id="oMG-LP-HUD"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
|
|
|
@ -21,6 +21,8 @@ protocol StatusTableViewCellDelegate {
|
|||
|
||||
func selected(status: Status)
|
||||
|
||||
func reply(to status: Status)
|
||||
|
||||
}
|
||||
|
||||
class StatusTableViewCell: UITableViewCell, PreferencesAdaptive {
|
||||
|
@ -99,6 +101,10 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func replyPressed(_ sender: Any) {
|
||||
delegate?.reply(to: status)
|
||||
}
|
||||
|
||||
@objc func accountPressed() {
|
||||
delegate?.selected(account: account)
|
||||
}
|
||||
|
|
|
@ -12,20 +12,20 @@
|
|||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="StatusTableViewCell" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="101"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="yNh-ac-v6c">
|
||||
<rect key="frame" x="16" y="8" width="343" height="85"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="yNh-ac-v6c">
|
||||
<rect key="frame" x="16" y="8" width="343" height="142"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Reblogged by Person" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lDH-50-AJZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="163.5" height="20.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ve3-Y1-NQH">
|
||||
<rect key="frame" x="0.0" y="28.5" width="343" height="56.5"/>
|
||||
<view contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="ve3-Y1-NQH">
|
||||
<rect key="frame" x="0.0" y="28.5" width="343" height="75.5"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="QMP-j2-HLn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HrJ-t9-KcD" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="58" y="28.5" width="285" height="28"/>
|
||||
<rect key="frame" x="58" y="28.5" width="285" height="47"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<constraint firstAttribute="trailing" secondItem="j89-zc-SFa" secondAttribute="trailing" id="D9z-3W-FHn"/>
|
||||
<constraint firstItem="QMP-j2-HLn" firstAttribute="top" secondItem="ve3-Y1-NQH" secondAttribute="top" id="PC4-Bi-QXm"/>
|
||||
<constraint firstItem="j89-zc-SFa" firstAttribute="leading" secondItem="gll-xe-FSr" secondAttribute="trailing" constant="8" id="XGL-3q-Urc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HrJ-t9-KcD" secondAttribute="bottom" id="XUe-ft-BPV"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HrJ-t9-KcD" secondAttribute="bottom" id="YAm-mK-YXb"/>
|
||||
<constraint firstItem="gll-xe-FSr" firstAttribute="leading" secondItem="QMP-j2-HLn" secondAttribute="trailing" constant="8" id="f00-ER-g7Q"/>
|
||||
<constraint firstItem="gll-xe-FSr" firstAttribute="top" secondItem="ve3-Y1-NQH" secondAttribute="top" id="ikJ-qd-ziU"/>
|
||||
<constraint firstAttribute="trailing" secondItem="HrJ-t9-KcD" secondAttribute="trailing" id="wCB-bW-AdR"/>
|
||||
|
@ -70,13 +70,25 @@
|
|||
<constraint firstItem="QMP-j2-HLn" firstAttribute="leading" secondItem="ve3-Y1-NQH" secondAttribute="leading" id="zeW-tQ-uJl"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Zlb-yt-NTw">
|
||||
<rect key="frame" x="0.0" y="112" width="343" height="30"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rKF-yF-KIa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="30"/>
|
||||
<state key="normal" title="Reply"/>
|
||||
<connections>
|
||||
<action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ohg-uU-d3Z"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="yNh-ac-v6c" secondAttribute="trailing" constant="16" id="2qQ-80-4Ui"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="yNh-ac-v6c" secondAttribute="bottom" constant="8" id="RKQ-BR-mlH"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="yNh-ac-v6c" secondAttribute="bottom" id="RKQ-BR-mlH"/>
|
||||
<constraint firstItem="yNh-ac-v6c" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="YVV-xZ-N4f"/>
|
||||
<constraint firstItem="yNh-ac-v6c" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="8" id="aAG-d7-dmV"/>
|
||||
</constraints>
|
||||
|
@ -89,7 +101,7 @@
|
|||
<outlet property="reblogLabel" destination="lDH-50-AJZ" id="uJf-Pt-cEP"/>
|
||||
<outlet property="usernameLabel" destination="j89-zc-SFa" id="see-Xd-3e9"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="40.799999999999997" y="27.436281859070466"/>
|
||||
<point key="canvasLocation" x="29.600000000000001" y="38.680659670164921"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
Loading…
Reference in New Issue