A bunch of VoiceOver/Voice Control stuff

This commit is contained in:
Shadowfacts 2019-09-26 20:53:22 -04:00
parent 5ebf651f76
commit 1808aaa3e8
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
11 changed files with 203 additions and 43 deletions

View File

@ -103,7 +103,9 @@ class ComposeViewController: UIViewController {
let toolbar = UIToolbar() let toolbar = UIToolbar()
contentWarningBarButtonItem = UIBarButtonItem(title: "CW", style: .plain, target: self, action: #selector(contentWarningButtonPressed)) contentWarningBarButtonItem = UIBarButtonItem(title: "CW", style: .plain, target: self, action: #selector(contentWarningButtonPressed))
contentWarningBarButtonItem.accessibilityLabel = NSLocalizedString("Add Content Warning", comment: "add CW accessibility label")
visibilityBarButtonItem = UIBarButtonItem(image: UIImage(systemName: Preferences.shared.defaultPostVisibility.imageName), style: .plain, target: self, action: #selector(visibilityButtonPressed)) visibilityBarButtonItem = UIBarButtonItem(image: UIImage(systemName: Preferences.shared.defaultPostVisibility.imageName), style: .plain, target: self, action: #selector(visibilityButtonPressed))
visibilityBarButtonItem.accessibilityLabel = String(format: NSLocalizedString("Visibility: %s", comment: "compose visiblity accessibility label"), Preferences.shared.defaultPostVisibility.displayName)
toolbar.items = [ toolbar.items = [
contentWarningBarButtonItem, contentWarningBarButtonItem,
visibilityBarButtonItem, visibilityBarButtonItem,
@ -231,6 +233,7 @@ class ComposeViewController: UIViewController {
fatalError("StatusFormat must have either an image or a title") fatalError("StatusFormat must have either an image or a title")
} }
item.tag = StatusFormat.allCases.firstIndex(of: format)! item.tag = StatusFormat.allCases.firstIndex(of: format)!
item.accessibilityLabel = format.accessibilityLabel
return item return item
} }
} }
@ -266,7 +269,8 @@ class ComposeViewController: UIViewController {
charactersRemainingLabel.textColor = .darkGray charactersRemainingLabel.textColor = .darkGray
postBarButtonItem.isEnabled = true postBarButtonItem.isEnabled = true
} }
charactersRemainingLabel.text = remaining.description charactersRemainingLabel.text = String(remaining)
charactersRemainingLabel.accessibilityLabel = String(format: NSLocalizedString("%d characters remaining", comment: "compose characters remaining accessibility label"), remaining)
} }
func updateHasChanges() { func updateHasChanges() {
@ -309,10 +313,16 @@ class ComposeViewController: UIViewController {
func contentWarningStateChanged() { func contentWarningStateChanged() {
contentWarningContainerView.isHidden = !contentWarningEnabled contentWarningContainerView.isHidden = !contentWarningEnabled
if contentWarningEnabled {
contentWarningBarButtonItem.accessibilityLabel = NSLocalizedString("Remove Content Warning", comment: "remove CW accessibility label")
} else {
contentWarningBarButtonItem.accessibilityLabel = NSLocalizedString("Add Content Warning", comment: "add CW accessibility label")
}
} }
func visibilityChanged() { func visibilityChanged() {
visibilityBarButtonItem.image = UIImage(systemName: visibility.imageName) visibilityBarButtonItem.image = UIImage(systemName: visibility.imageName)
visibilityBarButtonItem.accessibilityLabel = String(format: NSLocalizedString("Visibility: %s", comment: "compose visiblity accessibility label"), Preferences.shared.defaultPostVisibility.displayName)
} }
func saveDraft() { func saveDraft() {

View File

@ -1,11 +1,10 @@
<?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="14810.12" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <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">
<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="14766.15"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<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"/>
<capability name="iOS 13.0 system colors" minToolsVersion="11.0"/>
</dependencies> </dependencies>
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ComposeViewController" customModule="Tusker" customModuleProvider="target"> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ComposeViewController" customModule="Tusker" customModuleProvider="target">
@ -44,11 +43,14 @@
<subviews> <subviews>
<view contentMode="scaleToFill" placeholderIntrinsicWidth="infinite" placeholderIntrinsicHeight="66" translatesAutoresizingMaskIntoConstraints="NO" id="zZ3-Gv-4P5" customClass="LargeAccountDetailView" customModule="Tusker" customModuleProvider="target"> <view contentMode="scaleToFill" placeholderIntrinsicWidth="infinite" placeholderIntrinsicHeight="66" translatesAutoresizingMaskIntoConstraints="NO" id="zZ3-Gv-4P5" customClass="LargeAccountDetailView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="336" height="66"/> <rect key="frame" x="0.0" y="0.0" width="336" height="66"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" notEnabled="YES"/>
</accessibility>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="500" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PMB-Wa-Ht0"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="500" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PMB-Wa-Ht0">
<rect key="frame" x="336" y="8" width="31" height="20.5"/> <rect key="frame" x="336" y="8" width="31" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="secondaryLabelColor"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
@ -66,7 +68,7 @@
<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="8" width="367" height="30"/>
<color key="backgroundColor" cocoaTouchSystemColor="secondarySystemBackgroundColor"/> <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"/>
</constraints> </constraints>
@ -86,7 +88,7 @@
<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"/>
<color key="backgroundColor" cocoaTouchSystemColor="secondarySystemBackgroundColor"/> <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" relation="greaterThanOrEqual" constant="150" id="ISI-jm-FxV"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="150" id="ISI-jm-FxV"/>
</constraints> </constraints>
@ -117,14 +119,14 @@
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Aqk-LY-jEj"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Aqk-LY-jEj">
<rect key="frame" x="0.0" y="0.0" width="375" height="1"/> <rect key="frame" x="0.0" y="0.0" width="375" height="1"/>
<color key="backgroundColor" cocoaTouchSystemColor="separatorColor"/> <color key="backgroundColor" systemColor="separatorColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="1" id="0C7-KP-bIQ"/> <constraint firstAttribute="height" constant="1" id="0C7-KP-bIQ"/>
</constraints> </constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cVn-xc-LH9"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cVn-xc-LH9">
<rect key="frame" x="0.0" y="79" width="375" height="1"/> <rect key="frame" x="0.0" y="79" width="375" height="1"/>
<color key="backgroundColor" cocoaTouchSystemColor="separatorColor"/> <color key="backgroundColor" systemColor="separatorColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="1" id="SZ4-5b-Hcf"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="1" id="SZ4-5b-Hcf"/>
<constraint firstAttribute="height" constant="1" id="VIz-vl-Um4"/> <constraint firstAttribute="height" constant="1" id="VIz-vl-Um4"/>
@ -137,7 +139,7 @@
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="18"/> <fontDescription key="fontDescription" type="system" pointSize="18"/>
<state key="normal" title=" Add image or video" image="photo" catalog="system"> <state key="normal" title=" Add image or video" image="photo" catalog="system">
<color key="titleColor" cocoaTouchSystemColor="systemBlueColor"/> <color key="titleColor" systemColor="systemBlueColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state> </state>
<connections> <connections>
<action selector="addAttachmentPressed:" destination="-1" eventType="touchUpInside" id="aUR-nx-O9u"/> <action selector="addAttachmentPressed:" destination="-1" eventType="touchUpInside" id="aUR-nx-O9u"/>
@ -182,7 +184,7 @@
<color key="trackTintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="trackTintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</progressView> </progressView>
</subviews> </subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="Tq7-6P-hMT" secondAttribute="trailing" id="GeN-8q-weq"/> <constraint firstAttribute="trailing" secondItem="Tq7-6P-hMT" secondAttribute="trailing" id="GeN-8q-weq"/>
<constraint firstItem="Heg-g4-sYM" firstAttribute="bottom" secondItem="6Z0-Vy-hMX" secondAttribute="bottom" id="Hf3-Cc-mVX"/> <constraint firstItem="Heg-g4-sYM" firstAttribute="bottom" secondItem="6Z0-Vy-hMX" secondAttribute="bottom" id="Hf3-Cc-mVX"/>
@ -198,6 +200,6 @@
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="photo" catalog="system" width="64" height="48"/> <image name="photo" catalog="system" width="64" height="46"/>
</resources> </resources>
</document> </document>

View File

@ -45,6 +45,19 @@ enum StatusFormat: CaseIterable {
return nil return nil
} }
} }
var accessibilityLabel: String {
switch self {
case .italics:
return NSLocalizedString("Italics", comment: "italics text format accessibility label")
case .bold:
return NSLocalizedString("Bold", comment: "bold text format accessibility label")
case .strikethrough:
return NSLocalizedString("Strikethrough", comment: "strikethrough text format accessibility label")
case .code:
return NSLocalizedString("Code", comment: "code text format accessibility label")
}
}
} }
typealias FormatInsertionResult = (prefix: String, suffix: String, insertionPoint: Int) typealias FormatInsertionResult = (prefix: String, suffix: String, insertionPoint: Int)

View File

@ -29,6 +29,7 @@ class LargeAccountDetailView: UIView {
usernameLabel.translatesAutoresizingMaskIntoConstraints = false usernameLabel.translatesAutoresizingMaskIntoConstraints = false
usernameLabel.font = .systemFont(ofSize: 17, weight: .light) usernameLabel.font = .systemFont(ofSize: 17, weight: .light)
usernameLabel.textColor = .secondaryLabel usernameLabel.textColor = .secondaryLabel
usernameLabel.isAccessibilityElement = false
addSubview(usernameLabel) addSubview(usernameLabel)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([

View File

@ -56,44 +56,57 @@ class AttachmentsContainerView: UIView {
if attachments.count > 0 { if attachments.count > 0 {
self.isHidden = false self.isHidden = false
var accessibilityElements = [Any]()
switch attachments.count { switch attachments.count {
case 1: case 1:
fillView(createAttachmentView(index: 0)) let attachmentView = createAttachmentView(index: 0)
fillView(attachmentView)
accessibilityElements.append(attachmentView)
case 2: case 2:
let left = createAttachmentView(index: 0) let left = createAttachmentView(index: 0)
let right = createAttachmentView(index: 1)
fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
left, left,
createAttachmentView(index: 1) right
])) ]))
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
left.halfWidth() left.halfWidth()
]) ])
accessibilityElements.append(left)
accessibilityElements.append(right)
case 3: case 3:
let left = createAttachmentView(index: 0) let left = createAttachmentView(index: 0)
let topRight = createAttachmentView(index: 1) let topRight = createAttachmentView(index: 1)
let bottomRight = createAttachmentView(index: 2)
fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
left, left,
createAttachmentsStack(axis: .vertical, arrangedSubviews: [ createAttachmentsStack(axis: .vertical, arrangedSubviews: [
topRight, topRight,
createAttachmentView(index: 2) bottomRight
]) ])
])) ]))
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
left.halfWidth(), left.halfWidth(),
topRight.halfHeight(), topRight.halfHeight(),
]) ])
accessibilityElements.append(left)
accessibilityElements.append(topRight)
accessibilityElements.append(bottomRight)
case 4: case 4:
let topLeft = createAttachmentView(index: 0) let topLeft = createAttachmentView(index: 0)
let bottomLeft = createAttachmentView(index: 2)
let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [ let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
topLeft, topLeft,
createAttachmentView(index: 2) bottomLeft
]) ])
let topRight = createAttachmentView(index: 1) let topRight = createAttachmentView(index: 1)
let bottomRight = createAttachmentView(index: 3)
fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
left, left,
createAttachmentsStack(axis: .vertical, arrangedSubviews: [ createAttachmentsStack(axis: .vertical, arrangedSubviews: [
topRight, topRight,
createAttachmentView(index: 3) bottomRight
]) ])
])) ]))
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
@ -101,6 +114,10 @@ class AttachmentsContainerView: UIView {
topLeft.halfHeight(), topLeft.halfHeight(),
topRight.halfHeight(), topRight.halfHeight(),
]) ])
accessibilityElements.append(topLeft)
accessibilityElements.append(topRight)
accessibilityElements.append(bottomLeft)
accessibilityElements.append(bottomRight)
default: // more than 4 default: // more than 4
let moreView = UIView() let moreView = UIView()
moreView.backgroundColor = .secondarySystemBackground moreView.backgroundColor = .secondarySystemBackground
@ -112,12 +129,13 @@ class AttachmentsContainerView: UIView {
moreLabel.textColor = .secondaryLabel moreLabel.textColor = .secondaryLabel
moreLabel.textAlignment = .center moreLabel.textAlignment = .center
moreLabel.translatesAutoresizingMaskIntoConstraints = false moreLabel.translatesAutoresizingMaskIntoConstraints = false
moreView.addSubview(moreLabel) moreView.accessibilityLabel = moreLabel.text
let topLeft = createAttachmentView(index: 0) let topLeft = createAttachmentView(index: 0)
let bottomLeft = createAttachmentView(index: 2)
let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [ let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
topLeft, topLeft,
createAttachmentView(index: 2) bottomLeft
]) ])
let topRight = createAttachmentView(index: 1) let topRight = createAttachmentView(index: 1)
fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ fillView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
@ -136,11 +154,17 @@ class AttachmentsContainerView: UIView {
moreView.topAnchor.constraint(equalTo: moreLabel.topAnchor), moreView.topAnchor.constraint(equalTo: moreLabel.topAnchor),
moreLabel.bottomAnchor.constraint(equalTo: moreView.bottomAnchor), moreLabel.bottomAnchor.constraint(equalTo: moreView.bottomAnchor),
]) ])
accessibilityElements.append(topLeft)
accessibilityElements.append(topRight)
accessibilityElements.append(bottomLeft)
accessibilityElements.append(moreView)
} }
self.accessibilityElements = accessibilityElements
} else { } else {
self.isHidden = true self.isHidden = true
} }
if status.sensitive { if status.sensitive {
contentHidden = true contentHidden = true
createBlurView() createBlurView()
@ -152,6 +176,9 @@ class AttachmentsContainerView: UIView {
let attachmentView = AttachmentView(attachment: attachments[index], index: index) let attachmentView = AttachmentView(attachment: attachments[index], index: index)
attachmentView.delegate = delegate attachmentView.delegate = delegate
attachmentView.translatesAutoresizingMaskIntoConstraints = false attachmentView.translatesAutoresizingMaskIntoConstraints = false
attachmentView.isAccessibilityElement = true
attachmentView.accessibilityTraits = [.image, .button]
attachmentView.accessibilityLabel = String(format: NSLocalizedString("Attachment %d", comment: "attachment at index accessiblity label"), index + 1)
attachmentViews.add(attachmentView) attachmentViews.add(attachmentView)
return attachmentView return attachmentView
} }

View File

@ -1,11 +1,10 @@
<?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="14810.11" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <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">
<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="14766.13"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<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"/>
<capability name="iOS 13.0 system colors" minToolsVersion="11.0"/>
</dependencies> </dependencies>
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
@ -32,8 +31,12 @@
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0yZ-71-eTj"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0yZ-71-eTj">
<rect key="frame" x="115" y="0.0" width="178" height="21"/> <rect key="frame" x="115" y="0.0" width="178" height="21"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
<bool key="isElement" value="NO"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="secondaryLabelColor"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Content" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OEF-Hj-v3f" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Content" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OEF-Hj-v3f" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
@ -56,7 +59,7 @@
</constraints> </constraints>
</view> </view>
</subviews> </subviews>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints> <constraints>
<constraint firstItem="2cE-sS-Uut" firstAttribute="height" relation="greaterThanOrEqual" secondItem="Ypn-Ed-MTq" secondAttribute="height" id="Fn3-o4-RGx"/> <constraint firstItem="2cE-sS-Uut" firstAttribute="height" relation="greaterThanOrEqual" secondItem="Ypn-Ed-MTq" secondAttribute="height" id="Fn3-o4-RGx"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="2cE-sS-Uut" secondAttribute="bottom" constant="8" id="G2d-Kz-c4e"/> <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="2cE-sS-Uut" secondAttribute="bottom" constant="8" id="G2d-Kz-c4e"/>

View File

@ -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="14865.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <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">
<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="14819.2"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<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,9 @@
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Fw7-OL-iy5"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Fw7-OL-iy5">
<rect key="frame" x="0.0" y="0.0" width="375" height="150"/> <rect key="frame" x="0.0" y="0.0" width="375" height="150"/>
<accessibility key="accessibilityConfiguration" label="User Profile Banner">
<bool key="isElement" value="YES"/>
</accessibility>
<constraints> <constraints>
<constraint firstAttribute="height" constant="150" id="y43-4B-slK"/> <constraint firstAttribute="height" constant="150" id="y43-4B-slK"/>
</constraints> </constraints>
@ -24,6 +27,9 @@
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tH8-sR-DHC"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tH8-sR-DHC">
<rect key="frame" x="2" y="2" width="116" height="116"/> <rect key="frame" x="2" y="2" width="116" height="116"/>
<accessibility key="accessibilityConfiguration" label="User Avatar">
<bool key="isElement" value="YES"/>
</accessibility>
<gestureRecognizers/> <gestureRecognizers/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="116" id="k9v-I0-Aoz"/> <constraint firstAttribute="width" constant="116" id="k9v-I0-Aoz"/>
@ -81,6 +87,7 @@
</stackView> </stackView>
<button opaque="NO" alpha="0.59999999999999998" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qiv-gB-kiX"> <button opaque="NO" alpha="0.59999999999999998" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qiv-gB-kiX">
<rect key="frame" x="323.5" y="120" width="35.5" height="22"/> <rect key="frame" x="323.5" y="120" width="35.5" height="22"/>
<accessibility key="accessibilityConfiguration" label="More Actions"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/> <fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="ellipsis" catalog="system"> <state key="normal" image="ellipsis" catalog="system">
@ -133,6 +140,6 @@
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="ellipsis" catalog="system" width="64" height="20"/> <image name="ellipsis" catalog="system" width="64" height="18"/>
</resources> </resources>
</document> </document>

View File

@ -25,19 +25,24 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
} }
} }
@IBOutlet weak var profileDetailContainerView: UIView!
@IBOutlet weak var avatarImageView: UIImageView!
@IBOutlet weak var displayNameLabel: UILabel! @IBOutlet weak var displayNameLabel: UILabel!
@IBOutlet weak var usernameLabel: UILabel! @IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var contentWarningLabel: UILabel! @IBOutlet weak var contentWarningLabel: UILabel!
@IBOutlet weak var collapseButton: UIButton! @IBOutlet weak var collapseButton: UIButton!
@IBOutlet weak var contentLabel: StatusContentLabel! @IBOutlet weak var contentLabel: StatusContentLabel!
@IBOutlet weak var avatarImageView: UIImageView!
@IBOutlet weak var favoriteAndReblogCountStackView: UIStackView! @IBOutlet weak var favoriteAndReblogCountStackView: UIStackView!
@IBOutlet weak var totalFavoritesButton: UIButton! @IBOutlet weak var totalFavoritesButton: UIButton!
@IBOutlet weak var totalReblogsButton: UIButton! @IBOutlet weak var totalReblogsButton: UIButton!
@IBOutlet weak var timestampAndClientLabel: UILabel! @IBOutlet weak var timestampAndClientLabel: UILabel!
@IBOutlet weak var attachmentsView: AttachmentsContainerView! @IBOutlet weak var attachmentsView: AttachmentsContainerView!
@IBOutlet weak var replyButton: UIButton!
@IBOutlet weak var favoriteButton: UIButton! @IBOutlet weak var favoriteButton: UIButton!
@IBOutlet weak var reblogButton: UIButton! @IBOutlet weak var reblogButton: UIButton!
@IBOutlet weak var moreButton: UIButton!
var profileAccessibilityElement: UIAccessibilityElement!
var statusID: String! var statusID: String!
var accountID: String! var accountID: String!
@ -87,6 +92,10 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
profileAccessibilityElement = UIAccessibilityElement(accessibilityContainer: self)
profileAccessibilityElement.accessibilityFrameInContainerSpace = profileDetailContainerView.convert(profileDetailContainerView.frame, to: self)
accessibilityElements = [profileAccessibilityElement!, contentWarningLabel!, collapseButton!, contentLabel!, totalFavoritesButton!, totalReblogsButton!, timestampAndClientLabel!, replyButton!, favoriteButton!, reblogButton!, moreButton!]
statusUpdater = MastodonCache.statusSubject statusUpdater = MastodonCache.statusSubject
.filter { $0.id == self.statusID } .filter { $0.id == self.statusID }
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
@ -136,6 +145,17 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
favorited = status.favourited ?? false favorited = status.favourited ?? false
reblogged = status.reblogged ?? false reblogged = status.reblogged ?? false
if favorited {
favoriteButton.accessibilityLabel = NSLocalizedString("Undo Favorite", comment: "undo favorite button accessibility label")
} else {
favoriteButton.accessibilityLabel = NSLocalizedString("Favorite", comment: "favorite button accessibility label")
}
if reblogged {
reblogButton.accessibilityLabel = NSLocalizedString("Undo Reblog", comment: "undo reblog button accessibility label")
} else {
reblogButton.accessibilityLabel = NSLocalizedString("Reblog", comment: "reblog button accessibility label")
}
// todo: localize me // todo: localize me
totalFavoritesButton.setTitle("\(status.favouritesCount) Favorite\(status.favouritesCount == 1 ? "" : "s")", for: .normal) totalFavoritesButton.setTitle("\(status.favouritesCount) Favorite\(status.favouritesCount == 1 ? "" : "s")", for: .normal)
totalReblogsButton.setTitle("\(status.reblogsCount) Reblog\(status.reblogsCount == 1 ? "" : "s")", for: .normal) totalReblogsButton.setTitle("\(status.reblogsCount) Reblog\(status.reblogsCount == 1 ? "" : "s")", for: .normal)
@ -152,6 +172,8 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
self.avatarURL = nil self.avatarURL = nil
} }
} }
profileAccessibilityElement.accessibilityLabel = account.realDisplayName
} }
@objc func updateUIForPreferences() { @objc func updateUIForPreferences() {
@ -202,6 +224,13 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
} else { } else {
collapseButton.setImage(buttonImage, for: .normal) collapseButton.setImage(buttonImage, for: .normal)
} }
if collapsed {
collapseButton.accessibilityLabel = NSLocalizedString("Expand Status", comment: "expand status button accessibility label")
} else {
collapseButton.accessibilityLabel = NSLocalizedString("Collapse Status", comment: "collapse status button accessibility label")
}
} }
@IBAction func replyPressed(_ sender: Any) { @IBAction func replyPressed(_ sender: Any) {

View File

@ -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="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <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">
<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="14824"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<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>
@ -54,6 +54,9 @@
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Content Warning" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cwQ-mR-L1b"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Content Warning" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cwQ-mR-L1b">
<rect key="frame" x="0.0" y="58" width="138" height="20.5"/> <rect key="frame" x="0.0" y="58" width="138" height="20.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -123,6 +126,9 @@
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sep 7, 2019 12:12:53 PM • Web" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YHN-wG-YWi"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sep 7, 2019 12:12:53 PM • Web" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YHN-wG-YWi">
<rect key="frame" x="0.0" y="222.5" width="213.5" height="18"/> <rect key="frame" x="0.0" y="222.5" width="213.5" height="18"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="15"/> <fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -138,14 +144,16 @@
<rect key="frame" x="0.0" y="257" width="343" height="18"/> <rect key="frame" x="0.0" y="257" width="343" height="18"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2cc-lE-AdG"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2cc-lE-AdG">
<rect key="frame" x="0.0" y="0.0" width="21.5" height="18"/> <rect key="frame" x="0.0" y="0.0" width="21" height="18"/>
<accessibility key="accessibilityConfiguration" label="Reply"/>
<state key="normal" image="arrowshape.turn.up.left.fill" catalog="system"/> <state key="normal" image="arrowshape.turn.up.left.fill" catalog="system"/>
<connections> <connections>
<action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="hsh-gx-Swo"/> <action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="hsh-gx-Swo"/>
</connections> </connections>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DhN-rJ-jdA"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DhN-rJ-jdA">
<rect key="frame" x="107.5" y="0.0" width="22.5" height="18"/> <rect key="frame" x="107" y="0.0" width="22" height="18"/>
<accessibility key="accessibilityConfiguration" label="Favorite"/>
<state key="normal" image="star.fill" catalog="system"/> <state key="normal" image="star.fill" catalog="system"/>
<connections> <connections>
<action selector="favoritePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Hkh-Zo-9Qu"/> <action selector="favoritePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Hkh-Zo-9Qu"/>
@ -153,6 +161,7 @@
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GUG-f7-Hdy"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GUG-f7-Hdy">
<rect key="frame" x="215.5" y="0.0" width="22.5" height="18"/> <rect key="frame" x="215.5" y="0.0" width="22.5" height="18"/>
<accessibility key="accessibilityConfiguration" label="Reblog"/>
<state key="normal" image="repeat" catalog="system"/> <state key="normal" image="repeat" catalog="system"/>
<connections> <connections>
<action selector="reblogPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="SAf-RN-q8N"/> <action selector="reblogPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="SAf-RN-q8N"/>
@ -160,6 +169,7 @@
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ujo-Ap-dmK"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ujo-Ap-dmK">
<rect key="frame" x="324" y="0.0" width="19" height="18"/> <rect key="frame" x="324" y="0.0" width="19" height="18"/>
<accessibility key="accessibilityConfiguration" label="More Actions"/>
<state key="normal" image="ellipsis" catalog="system"/> <state key="normal" image="ellipsis" catalog="system"/>
<connections> <connections>
<action selector="morePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="dWb-67-CoL"/> <action selector="morePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="dWb-67-CoL"/>
@ -199,7 +209,10 @@
<outlet property="displayNameLabel" destination="lZY-2e-17d" id="7og-23-eHy"/> <outlet property="displayNameLabel" destination="lZY-2e-17d" id="7og-23-eHy"/>
<outlet property="favoriteAndReblogCountStackView" destination="HZv-qj-gi6" id="jC9-cA-dXg"/> <outlet property="favoriteAndReblogCountStackView" destination="HZv-qj-gi6" id="jC9-cA-dXg"/>
<outlet property="favoriteButton" destination="DhN-rJ-jdA" id="b2Q-ch-kSP"/> <outlet property="favoriteButton" destination="DhN-rJ-jdA" id="b2Q-ch-kSP"/>
<outlet property="moreButton" destination="Ujo-Ap-dmK" id="2ba-5w-HDx"/>
<outlet property="profileDetailContainerView" destination="Cnd-Fj-B7l" id="wco-VB-VQx"/>
<outlet property="reblogButton" destination="GUG-f7-Hdy" id="WtT-Ph-DQm"/> <outlet property="reblogButton" destination="GUG-f7-Hdy" id="WtT-Ph-DQm"/>
<outlet property="replyButton" destination="2cc-lE-AdG" id="My8-JV-Nho"/>
<outlet property="timestampAndClientLabel" destination="YHN-wG-YWi" id="Onb-fe-qwG"/> <outlet property="timestampAndClientLabel" destination="YHN-wG-YWi" id="Onb-fe-qwG"/>
<outlet property="totalFavoritesButton" destination="yyj-Bs-Vjq" id="4pV-Qi-Z2X"/> <outlet property="totalFavoritesButton" destination="yyj-Bs-Vjq" id="4pV-Qi-Z2X"/>
<outlet property="totalReblogsButton" destination="dem-vG-cPB" id="i9E-Qn-d76"/> <outlet property="totalReblogsButton" destination="dem-vG-cPB" id="i9E-Qn-d76"/>
@ -210,9 +223,9 @@
</objects> </objects>
<resources> <resources>
<image name="arrowshape.turn.up.left.fill" catalog="system" width="64" height="52"/> <image name="arrowshape.turn.up.left.fill" catalog="system" width="64" height="52"/>
<image name="chevron.down" catalog="system" width="64" height="34"/> <image name="chevron.down" catalog="system" width="64" height="36"/>
<image name="ellipsis" catalog="system" width="64" height="20"/> <image name="ellipsis" catalog="system" width="64" height="18"/>
<image name="repeat" catalog="system" width="64" height="50"/> <image name="repeat" catalog="system" width="64" height="48"/>
<image name="star.fill" catalog="system" width="64" height="58"/> <image name="star.fill" catalog="system" width="64" height="58"/>
</resources> </resources>
</document> </document>

View File

@ -16,6 +16,13 @@ protocol StatusTableViewCellDelegate: TuskerNavigationDelegate {
class StatusTableViewCell: UITableViewCell { class StatusTableViewCell: UITableViewCell {
static let relativeDateFormatter: RelativeDateTimeFormatter = {
let formatter = RelativeDateTimeFormatter()
formatter.dateTimeStyle = .numeric
formatter.unitsStyle = .short
return formatter
}()
var delegate: StatusTableViewCellDelegate? { var delegate: StatusTableViewCellDelegate? {
didSet { didSet {
contentLabel.navigationDelegate = delegate contentLabel.navigationDelegate = delegate
@ -31,8 +38,10 @@ class StatusTableViewCell: UITableViewCell {
@IBOutlet weak var reblogLabel: UILabel! @IBOutlet weak var reblogLabel: UILabel!
@IBOutlet weak var timestampLabel: UILabel! @IBOutlet weak var timestampLabel: UILabel!
@IBOutlet weak var attachmentsView: AttachmentsContainerView! @IBOutlet weak var attachmentsView: AttachmentsContainerView!
@IBOutlet weak var replyButton: UIButton!
@IBOutlet weak var favoriteButton: UIButton! @IBOutlet weak var favoriteButton: UIButton!
@IBOutlet weak var reblogButton: UIButton! @IBOutlet weak var reblogButton: UIButton!
@IBOutlet weak var moreButton: UIButton!
var statusID: String! var statusID: String!
var accountID: String! var accountID: String!
@ -83,6 +92,9 @@ class StatusTableViewCell: UITableViewCell {
collapseButton.layer.masksToBounds = true collapseButton.layer.masksToBounds = true
collapseButton.layer.cornerRadius = 5 collapseButton.layer.cornerRadius = 5
accessibilityElements = [reblogLabel!, displayNameLabel!, contentWarningLabel!, collapseButton!, contentLabel!, attachmentsView!]
attachmentsView.isAccessibilityElement = true
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
statusUpdater = MastodonCache.statusSubject statusUpdater = MastodonCache.statusSubject
@ -129,6 +141,8 @@ class StatusTableViewCell: UITableViewCell {
updateTimestamp() updateTimestamp()
attachmentsView.updateUI(status: status) attachmentsView.updateUI(status: status)
attachmentsView.isAccessibilityElement = status.attachments.count > 0
attachmentsView.accessibilityLabel = String(format: NSLocalizedString("%d attachments", comment: "status attachments count accessibility label"), status.attachments.count)
let realStatus = status.reblog ?? status let realStatus = status.reblog ?? status
updateStatusState(status: realStatus) updateStatusState(status: realStatus)
@ -144,6 +158,17 @@ class StatusTableViewCell: UITableViewCell {
private func updateStatusState(status: Status) { private func updateStatusState(status: Status) {
favorited = status.favourited ?? false favorited = status.favourited ?? false
reblogged = status.reblogged ?? false reblogged = status.reblogged ?? false
if favorited {
favoriteButton.accessibilityLabel = NSLocalizedString("Undo Favorite", comment: "undo favorite button accessibility label")
} else {
favoriteButton.accessibilityLabel = NSLocalizedString("Favorite", comment: "favorite button accessibility label")
}
if reblogged {
reblogButton.accessibilityLabel = NSLocalizedString("Undo Reblog", comment: "undo reblog button accessibility label")
} else {
reblogButton.accessibilityLabel = NSLocalizedString("Reblog", comment: "reblog button accessibility label")
}
} }
private func updateUI(account: Account) { private func updateUI(account: Account) {
@ -173,6 +198,8 @@ class StatusTableViewCell: UITableViewCell {
guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") } guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") }
timestampLabel.text = status.createdAt.timeAgoString() timestampLabel.text = status.createdAt.timeAgoString()
timestampLabel.accessibilityLabel = StatusTableViewCell.relativeDateFormatter.localizedString(for: status.createdAt, relativeTo: Date())
let delay: DispatchTimeInterval? let delay: DispatchTimeInterval?
switch status.createdAt.timeAgo().1 { switch status.createdAt.timeAgo().1 {
case .second: case .second:
@ -240,6 +267,12 @@ class StatusTableViewCell: UITableViewCell {
} else { } else {
collapseButton.setImage(buttonImage, for: .normal) collapseButton.setImage(buttonImage, for: .normal)
} }
if collapsed {
collapseButton.accessibilityLabel = NSLocalizedString("Expand Status", comment: "expand status button accessibility label")
} else {
collapseButton.accessibilityLabel = NSLocalizedString("Collapse Status", comment: "collapse status button accessibility label")
}
} }
@IBAction func replyPressed(_ sender: Any) { @IBAction func replyPressed(_ sender: Any) {

View File

@ -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="14865.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <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">
<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="14819.2"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
<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>
@ -27,6 +27,9 @@
<subviews> <subviews>
<imageView contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="QMP-j2-HLn"> <imageView 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"/> <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<accessibility key="accessibilityConfiguration" label="User Avatar">
<bool key="isElement" value="YES"/>
</accessibility>
<gestureRecognizers/> <gestureRecognizers/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="50" id="KZ8-d7-8UK"/> <constraint firstAttribute="width" constant="50" id="KZ8-d7-8UK"/>
@ -41,6 +44,9 @@
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" horizontalCompressionResistancePriority="749" verticalCompressionResistancePriority="752" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gll-xe-FSr"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" horizontalCompressionResistancePriority="749" verticalCompressionResistancePriority="752" text="Display name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gll-xe-FSr">
<rect key="frame" x="0.0" y="0.0" width="107" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="107" height="20.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
</accessibility>
<gestureRecognizers/> <gestureRecognizers/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/> <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<nil key="textColor"/> <nil key="textColor"/>
@ -48,6 +54,9 @@
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" horizontalCompressionResistancePriority="748" verticalCompressionResistancePriority="752" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j89-zc-SFa"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" horizontalCompressionResistancePriority="748" verticalCompressionResistancePriority="752" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j89-zc-SFa">
<rect key="frame" x="115" y="0.0" width="129.5" height="20.5"/> <rect key="frame" x="115" y="0.0" width="129.5" height="20.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
</accessibility>
<gestureRecognizers/> <gestureRecognizers/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/> <fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
@ -55,6 +64,10 @@
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="752" text="2m" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="35d-EA-ReR"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="752" text="2m" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="35d-EA-ReR">
<rect key="frame" x="252.5" y="0.0" width="24.5" height="20.5"/> <rect key="frame" x="252.5" y="0.0" width="24.5" height="20.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/> <fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -66,6 +79,9 @@
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="755" text="Content Warning" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="inI-Og-YiU"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="755" text="Content Warning" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="inI-Og-YiU">
<rect key="frame" x="0.0" y="24.5" width="277" height="20.5"/> <rect key="frame" x="0.0" y="24.5" width="277" height="20.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -114,14 +130,16 @@
<rect key="frame" x="0.0" y="202" width="343" height="22"/> <rect key="frame" x="0.0" y="202" width="343" height="22"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rKF-yF-KIa"> <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rKF-yF-KIa">
<rect key="frame" x="0.0" y="0.0" width="21.5" height="22"/> <rect key="frame" x="0.0" y="0.0" width="21" height="22"/>
<accessibility key="accessibilityConfiguration" label="Reply"/>
<state key="normal" image="arrowshape.turn.up.left.fill" catalog="system"/> <state key="normal" image="arrowshape.turn.up.left.fill" catalog="system"/>
<connections> <connections>
<action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ohg-uU-d3Z"/> <action selector="replyPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ohg-uU-d3Z"/>
</connections> </connections>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="x0t-TR-jJ4"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="x0t-TR-jJ4">
<rect key="frame" x="107.5" y="0.0" width="22.5" height="22"/> <rect key="frame" x="107" y="0.0" width="22" height="22"/>
<accessibility key="accessibilityConfiguration" label="Favorite"/>
<state key="normal" image="star.fill" catalog="system"/> <state key="normal" image="star.fill" catalog="system"/>
<connections> <connections>
<action selector="favoritePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="gKJ-Hu-za3"/> <action selector="favoritePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="gKJ-Hu-za3"/>
@ -129,6 +147,7 @@
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6tW-z8-Qh9"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6tW-z8-Qh9">
<rect key="frame" x="215.5" y="0.0" width="22.5" height="22"/> <rect key="frame" x="215.5" y="0.0" width="22.5" height="22"/>
<accessibility key="accessibilityConfiguration" label="Reblog"/>
<state key="normal" image="repeat" catalog="system"/> <state key="normal" image="repeat" catalog="system"/>
<connections> <connections>
<action selector="reblogPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="JQI-VT-wTt"/> <action selector="reblogPressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="JQI-VT-wTt"/>
@ -136,6 +155,7 @@
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="982-J4-NGl"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="982-J4-NGl">
<rect key="frame" x="324" y="0.0" width="19" height="22"/> <rect key="frame" x="324" y="0.0" width="19" height="22"/>
<accessibility key="accessibilityConfiguration" label="More Actions"/>
<state key="normal" image="ellipsis" catalog="system"/> <state key="normal" image="ellipsis" catalog="system"/>
<connections> <connections>
<action selector="morePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="dcV-Ez-EIe"/> <action selector="morePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="dcV-Ez-EIe"/>
@ -168,8 +188,10 @@
<outlet property="contentWarningLabel" destination="inI-Og-YiU" id="2jf-6J-JUU"/> <outlet property="contentWarningLabel" destination="inI-Og-YiU" id="2jf-6J-JUU"/>
<outlet property="displayNameLabel" destination="gll-xe-FSr" id="63y-He-xy1"/> <outlet property="displayNameLabel" destination="gll-xe-FSr" id="63y-He-xy1"/>
<outlet property="favoriteButton" destination="x0t-TR-jJ4" id="Ohz-bs-Ebr"/> <outlet property="favoriteButton" destination="x0t-TR-jJ4" id="Ohz-bs-Ebr"/>
<outlet property="moreButton" destination="982-J4-NGl" id="Xga-I4-CzK"/>
<outlet property="reblogButton" destination="6tW-z8-Qh9" id="i9h-QA-ZPd"/> <outlet property="reblogButton" destination="6tW-z8-Qh9" id="i9h-QA-ZPd"/>
<outlet property="reblogLabel" destination="lDH-50-AJZ" id="uJf-Pt-cEP"/> <outlet property="reblogLabel" destination="lDH-50-AJZ" id="uJf-Pt-cEP"/>
<outlet property="replyButton" destination="rKF-yF-KIa" id="rul-lk-bIR"/>
<outlet property="timestampLabel" destination="35d-EA-ReR" id="8EW-mb-LAb"/> <outlet property="timestampLabel" destination="35d-EA-ReR" id="8EW-mb-LAb"/>
<outlet property="usernameLabel" destination="j89-zc-SFa" id="see-Xd-3e9"/> <outlet property="usernameLabel" destination="j89-zc-SFa" id="see-Xd-3e9"/>
</connections> </connections>
@ -178,9 +200,9 @@
</objects> </objects>
<resources> <resources>
<image name="arrowshape.turn.up.left.fill" catalog="system" width="64" height="52"/> <image name="arrowshape.turn.up.left.fill" catalog="system" width="64" height="52"/>
<image name="chevron.down" catalog="system" width="64" height="34"/> <image name="chevron.down" catalog="system" width="64" height="36"/>
<image name="ellipsis" catalog="system" width="64" height="20"/> <image name="ellipsis" catalog="system" width="64" height="18"/>
<image name="repeat" catalog="system" width="64" height="50"/> <image name="repeat" catalog="system" width="64" height="48"/>
<image name="star.fill" catalog="system" width="64" height="58"/> <image name="star.fill" catalog="system" width="64" height="58"/>
</resources> </resources>
</document> </document>