Add visual indication that a url has been validated in a profile's fields
This commit is contained in:
parent
23867b0be1
commit
c3009d6009
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"provides-namespace" : true
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue