Show fields in profiles

Closes #19
This commit is contained in:
Shadowfacts 2019-04-01 19:34:50 -04:00
parent 9c0624b79e
commit d94a0050b7
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 56 additions and 13 deletions

View File

@ -124,7 +124,7 @@ extension Account: CustomDebugStringConvertible {
extension Account { extension Account {
public struct Field: Codable { public struct Field: Codable {
let name: String public let name: String
let value: String public let value: String
} }
} }

View File

@ -180,8 +180,8 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti
case 0: case 0:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? ProfileHeaderTableViewCell else { fatalError() } guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? ProfileHeaderTableViewCell else { fatalError() }
cell.selectionStyle = .none cell.selectionStyle = .none
cell.updateUI(for: accountID)
cell.delegate = self cell.delegate = self
cell.updateUI(for: accountID)
return cell return cell
case 1: case 1:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() } guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() }

View File

@ -15,11 +15,7 @@ protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate {
class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive { class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
var delegate: ProfileHeaderTableViewCellDelegate? { var delegate: ProfileHeaderTableViewCellDelegate?
didSet {
noteLabel.navigationDelegate = delegate
}
}
@IBOutlet weak var headerImageView: UIImageView! @IBOutlet weak var headerImageView: UIImageView!
@IBOutlet weak var avatarContainerView: UIView! @IBOutlet weak var avatarContainerView: UIView!
@ -28,6 +24,9 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
@IBOutlet weak var usernameLabel: UILabel! @IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var followsYouLabel: UILabel! @IBOutlet weak var followsYouLabel: UILabel!
@IBOutlet weak var noteLabel: StatusContentLabel! @IBOutlet weak var noteLabel: StatusContentLabel!
@IBOutlet weak var fieldsStackView: UIStackView!
@IBOutlet weak var fieldNamesStackView: UIStackView!
@IBOutlet weak var fieldValuesStack: UIStackView!
var accountID: String! var accountID: String!
@ -52,7 +51,9 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
} }
func updateUI(for accountID: String) { func updateUI(for accountID: String) {
guard accountID != self.accountID else { return }
self.accountID = accountID self.accountID = accountID
guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID)") } guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID)") }
updateUIForPreferences() updateUIForPreferences()
@ -76,7 +77,9 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
} }
} }
noteLabel.navigationDelegate = delegate
noteLabel.setTextFromHtml(account.note) noteLabel.setTextFromHtml(account.note)
noteLabel.setEmojis(account.emojis)
if accountID != MastodonController.account.id { if accountID != MastodonController.account.id {
// don't show relationship label for the user's own account // don't show relationship label for the user's own account
@ -90,6 +93,29 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
} }
} }
} }
if let fields = account.fields, !fields.isEmpty {
fieldsStackView.isHidden = false
for field in fields {
let nameLabel = UILabel()
nameLabel.text = field.name
nameLabel.font = .boldSystemFont(ofSize: 17)
nameLabel.textAlignment = .right
fieldNamesStackView.addArrangedSubview(nameLabel)
let valueLabel = ContentLabel()
valueLabel.setTextFromHtml(field.value)
valueLabel.setEmojis(account.emojis)
valueLabel.font = .systemFont(ofSize: 17)
valueLabel.textAlignment = .left
valueLabel.awakeFromNib() // TODO: this shouldn't be necessary
valueLabel.navigationDelegate = delegate
fieldValuesStack.addArrangedSubview(valueLabel)
}
} else {
fieldsStackView.isHidden = true
}
} }
override func prepareForReuse() { override func prepareForReuse() {

View File

@ -1,10 +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="14460.15" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait"> <device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.9"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<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,7 +54,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="DfO-uD-UNI"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="DfO-uD-UNI">
<rect key="frame" x="16" y="218" width="343" height="70"/> <rect key="frame" x="16" y="218" width="343" height="12"/>
<subviews> <subviews>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Follows you" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a32-1a-xXZ"> <label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Follows you" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a32-1a-xXZ">
<rect key="frame" x="0.0" y="0.0" width="75.5" height="0.0"/> <rect key="frame" x="0.0" y="0.0" width="75.5" height="0.0"/>
@ -63,13 +63,24 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Note" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I0n-aP-dJP" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Note" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I0n-aP-dJP" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="37" height="70"/> <rect key="frame" x="0.0" y="0.0" width="37" height="12"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="sHU-GU-klv">
<rect key="frame" x="16" y="238" width="343" height="50"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="pV2-Mz-54W">
<rect key="frame" x="0.0" y="0.0" width="147" height="50"/>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="oza-9d-8v4">
<rect key="frame" x="155" y="0.0" width="188" height="50"/>
</stackView>
</subviews>
</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="309" y="117" width="50" height="25"/> <rect key="frame" x="309" y="117" width="50" height="25"/>
<constraints> <constraints>
@ -94,10 +105,13 @@
<constraint firstItem="DfO-uD-UNI" firstAttribute="top" secondItem="KyB-ey-l11" secondAttribute="bottom" constant="8" id="Ljh-8x-yI3"/> <constraint firstItem="DfO-uD-UNI" firstAttribute="top" secondItem="KyB-ey-l11" secondAttribute="bottom" constant="8" id="Ljh-8x-yI3"/>
<constraint firstItem="Fw7-OL-iy5" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="LqH-lE-AIe"/> <constraint firstItem="Fw7-OL-iy5" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="LqH-lE-AIe"/>
<constraint firstItem="KyB-ey-l11" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="NN7-5B-k1Q"/> <constraint firstItem="KyB-ey-l11" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="NN7-5B-k1Q"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="DfO-uD-UNI" secondAttribute="bottom" constant="8" id="aj3-iF-QBe"/> <constraint firstItem="sHU-GU-klv" firstAttribute="top" secondItem="DfO-uD-UNI" secondAttribute="bottom" constant="8" id="Vza-1s-qbG"/>
<constraint firstAttribute="trailingMargin" secondItem="sHU-GU-klv" secondAttribute="trailing" id="XJa-zP-Ma2"/>
<constraint firstItem="sHU-GU-klv" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" id="cSX-WD-2aJ"/>
<constraint firstItem="Fw7-OL-iy5" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="d1j-6d-hBb"/> <constraint firstItem="Fw7-OL-iy5" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="d1j-6d-hBb"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="LjK-72-Bez" secondAttribute="trailing" constant="16" id="hn9-c3-iNH"/> <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="LjK-72-Bez" secondAttribute="trailing" constant="16" id="hn9-c3-iNH"/>
<constraint firstItem="MIj-OR-NOR" firstAttribute="leading" secondItem="KyB-ey-l11" secondAttribute="trailing" constant="8" id="iG7-yZ-9u3"/> <constraint firstItem="MIj-OR-NOR" firstAttribute="leading" secondItem="KyB-ey-l11" secondAttribute="trailing" constant="8" id="iG7-yZ-9u3"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="sHU-GU-klv" secondAttribute="bottom" constant="8" id="iRf-l0-ZZX"/>
<constraint firstItem="MIj-OR-NOR" firstAttribute="top" secondItem="LjK-72-Bez" secondAttribute="bottom" constant="8" id="nMM-6t-bjX"/> <constraint firstItem="MIj-OR-NOR" firstAttribute="top" secondItem="LjK-72-Bez" secondAttribute="bottom" constant="8" id="nMM-6t-bjX"/>
<constraint firstAttribute="trailing" secondItem="qiv-gB-kiX" secondAttribute="trailing" constant="16" id="nYG-p6-Ezm"/> <constraint firstAttribute="trailing" secondItem="qiv-gB-kiX" secondAttribute="trailing" constant="16" id="nYG-p6-Ezm"/>
<constraint firstItem="qiv-gB-kiX" firstAttribute="bottom" secondItem="Fw7-OL-iy5" secondAttribute="bottom" constant="-8" id="pg7-L7-u2f"/> <constraint firstItem="qiv-gB-kiX" firstAttribute="bottom" secondItem="Fw7-OL-iy5" secondAttribute="bottom" constant="-8" id="pg7-L7-u2f"/>
@ -109,6 +123,9 @@
<outlet property="avatarContainerView" destination="KyB-ey-l11" id="45s-jV-l8L"/> <outlet property="avatarContainerView" destination="KyB-ey-l11" id="45s-jV-l8L"/>
<outlet property="avatarImageView" destination="tH8-sR-DHC" id="6ll-yL-g1o"/> <outlet property="avatarImageView" destination="tH8-sR-DHC" id="6ll-yL-g1o"/>
<outlet property="displayNameLabel" destination="LjK-72-Bez" id="nIU-ey-H1C"/> <outlet property="displayNameLabel" destination="LjK-72-Bez" id="nIU-ey-H1C"/>
<outlet property="fieldNamesStackView" destination="pV2-Mz-54W" id="xfG-60-K0s"/>
<outlet property="fieldValuesStack" destination="oza-9d-8v4" id="UIS-KM-5fR"/>
<outlet property="fieldsStackView" destination="sHU-GU-klv" id="Gli-Gf-Ubh"/>
<outlet property="followsYouLabel" destination="a32-1a-xXZ" id="phY-0L-NnN"/> <outlet property="followsYouLabel" destination="a32-1a-xXZ" id="phY-0L-NnN"/>
<outlet property="headerImageView" destination="Fw7-OL-iy5" id="6sv-E5-D73"/> <outlet property="headerImageView" destination="Fw7-OL-iy5" id="6sv-E5-D73"/>
<outlet property="noteLabel" destination="I0n-aP-dJP" id="7yW-mE-jxY"/> <outlet property="noteLabel" destination="I0n-aP-dJP" id="7yW-mE-jxY"/>