Add visual indication that a url has been validated in a profile's fields

This commit is contained in:
David Godfrey 2022-11-11 20:34:26 +00:00
parent 23867b0be1
commit c3009d6009
8 changed files with 121 additions and 5 deletions

View File

@ -23,6 +23,7 @@ extension ProfileFieldItem {
var name: CurrentValueSubject<String, Never>
var value: CurrentValueSubject<String, Never>
var verifiedAt: CurrentValueSubject<Date?, Never>
let emojiMeta: MastodonContent.Emojis
@ -30,11 +31,13 @@ extension ProfileFieldItem {
id: UUID = UUID(),
name: String,
value: String,
verifiedAt: Date?,
emojiMeta: MastodonContent.Emojis
) {
self.id = id
self.name = CurrentValueSubject(name)
self.value = CurrentValueSubject(value)
self.verifiedAt = CurrentValueSubject(verifiedAt)
self.emojiMeta = emojiMeta
}
@ -45,6 +48,7 @@ extension ProfileFieldItem {
return lhs.id == rhs.id
&& lhs.name.value == rhs.name.value
&& lhs.value.value == rhs.value.value
&& lhs.verifiedAt.value == rhs.verifiedAt.value
&& lhs.emojiMeta == rhs.emojiMeta
}

View File

@ -8,6 +8,7 @@
import os
import UIKit
import Combine
import MastodonAsset
import MastodonCore
import MastodonMeta
import MastodonLocalization
@ -57,7 +58,17 @@ extension ProfileFieldSection {
// set background
var backgroundConfiguration = UIBackgroundConfiguration.listPlainCell()
backgroundConfiguration.backgroundColor = UIColor.secondarySystemBackground
if (field.verifiedAt.value != nil) {
backgroundConfiguration.backgroundColor = Asset.Scene.Profile.About.bioAboutFieldValidatedBackground.color
}
cell.backgroundConfiguration = backgroundConfiguration
// set checkmark
cell.checkmark.isHidden = true
if let verifiedAt = field.verifiedAt.value {
cell.checkmark.isHidden = false
cell.checkmark.accessibilityLabel = "Ownership of this link was checked on \(verifiedAt)" // TODO: I18N / L10N
}
cell.delegate = configuration.profileFieldCollectionViewCellDelegate
}

View File

@ -26,6 +26,8 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
let keyMetaLabel = MetaLabel(style: .profileFieldName)
let valueMetaLabel = MetaLabel(style: .profileFieldValue)
let checkmark = UIImageView(image: Asset.Editing.checkmark.image.withRenderingMode(.alwaysTemplate))
override func prepareForReuse() {
super.prepareForReuse()
@ -47,6 +49,8 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
extension ProfileFieldCollectionViewCell {
private func _init() {
checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldValidatedCheckmark.color;
// containerStackView: V - [ metaContainer | plainContainer ]
let containerStackView = UIStackView()
containerStackView.axis = .vertical
@ -63,14 +67,21 @@ extension ProfileFieldCollectionViewCell {
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 11),
])
// metaContainer: V - [ keyMetaLabel | valueMetaLabel ]
// metaContainer: V - [ keyMetaLabel | valueContainer ]
let metaContainer = UIStackView()
metaContainer.axis = .vertical
metaContainer.spacing = 2
containerStackView.addArrangedSubview(metaContainer)
// valueContainer: H - [ valueMetaLabel | checkmark ]
let valueContainer = UIStackView()
valueContainer.axis = .horizontal
valueContainer.spacing = 2
metaContainer.addArrangedSubview(keyMetaLabel)
metaContainer.addArrangedSubview(valueMetaLabel)
valueContainer.addArrangedSubview(valueMetaLabel)
valueContainer.addArrangedSubview(checkmark)
metaContainer.addArrangedSubview(valueContainer)
keyMetaLabel.linkDelegate = self
valueMetaLabel.linkDelegate = self

View File

@ -52,7 +52,7 @@ final class ProfileAboutViewModel {
$emojiMeta
)
.map { fields, emojiMeta in
fields.map { ProfileFieldItem.FieldValue(name: $0.name, value: $0.value, emojiMeta: emojiMeta) }
fields.map { ProfileFieldItem.FieldValue(name: $0.name, value: $0.value, verifiedAt: $0.verifiedAt, emojiMeta: emojiMeta) }
}
.assign(to: &profileInfo.$fields)
@ -72,6 +72,7 @@ final class ProfileAboutViewModel {
ProfileFieldItem.FieldValue(
name: field.name,
value: field.value,
verifiedAt: field.verifiedAt,
emojiMeta: [:] // no use for editing
)
} ?? []
@ -92,7 +93,7 @@ extension ProfileAboutViewModel {
func appendFieldItem() {
var fields = profileInfoEditing.fields
guard fields.count < ProfileHeaderViewModel.maxProfileFieldCount else { return }
fields.append(ProfileFieldItem.FieldValue(name: "", value: "", emojiMeta: [:]))
fields.append(ProfileFieldItem.FieldValue(name: "", value: "", verifiedAt: nil, emojiMeta: [:]))
profileInfoEditing.fields = fields
}
@ -112,7 +113,7 @@ extension ProfileAboutViewModel: ProfileViewModelEditable {
let isFieldsEqual: Bool = {
let originalFields = self.accountForEdit?.source?.fields?.compactMap { field in
ProfileFieldItem.FieldValue(name: field.name, value: field.value, emojiMeta: [:])
ProfileFieldItem.FieldValue(name: field.name, value: field.value, verifiedAt: nil, emojiMeta: [:])
} ?? []
let editFields = profileInfoEditing.fields
guard editFields.count == originalFields.count else { return false }

View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.852",
"green" : "0.894",
"red" : "0.835"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.354",
"green" : "0.353",
"red" : "0.268"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.371",
"green" : "0.565",
"red" : "0.290"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.603",
"green" : "0.742",
"red" : "0.476"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -163,6 +163,10 @@ public enum Asset {
public static let textFieldBackground = ColorAsset(name: "Scene/Onboarding/textField.background")
}
public enum Profile {
public enum About {
public static let bioAboutFieldValidatedBackground = ColorAsset(name: "Scene/Profile/About/bio.about.field.validated.background")
public static let bioAboutFieldValidatedCheckmark = ColorAsset(name: "Scene/Profile/About/bio.about.field.validated.checkmark")
}
public enum Banner {
public static let bioEditBackgroundGray = ColorAsset(name: "Scene/Profile/Banner/bio.edit.background.gray")
public static let nameEditBackgroundGray = ColorAsset(name: "Scene/Profile/Banner/name.edit.background.gray")