IOS-80 Add AXCustomContent to ProfileCardView (#979)

This commit is contained in:
Jed Fox 2023-03-20 03:02:41 -04:00 committed by GitHub
parent 85ad331a5e
commit f0753e9d0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 107 additions and 11 deletions

View File

@ -508,7 +508,8 @@
"my_followers": "followers",
"other_posts": "posts",
"other_following": "following",
"other_followers": "followers"
"other_followers": "followers",
"familiar_followers": "mutuals"
},
"fields": {
"joined": "Joined",

View File

@ -553,7 +553,8 @@
"my_followers": "followers",
"other_posts": "posts",
"other_following": "following",
"other_followers": "followers"
"other_followers": "followers",
"familiar_followers": "mutuals"
},
"fields": {
"joined": "Joined",

View File

@ -70,7 +70,13 @@ extension DiscoveryForYouViewController {
.receive(on: DispatchQueue.main)
.sink { [weak self] isFetching in
guard let self = self else { return }
if !isFetching {
if isFetching {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if !self.refreshControl.isRefreshing {
self.refreshControl.beginRefreshing()
}
}
} else {
self.refreshControl.endRefreshing()
}
}

View File

@ -899,6 +899,8 @@ public enum L10n {
public static let showBannerImage = L10n.tr("Localizable", "Scene.Profile.Accessibility.ShowBannerImage", fallback: "Show banner image")
}
public enum Dashboard {
/// mutuals
public static let familiarFollowers = L10n.tr("Localizable", "Scene.Profile.Dashboard.FamiliarFollowers", fallback: "mutuals")
/// followers
public static let myFollowers = L10n.tr("Localizable", "Scene.Profile.Dashboard.MyFollowers", fallback: "followers")
/// following

View File

@ -311,6 +311,7 @@ uploaded to Mastodon.";
"Scene.Profile.Accessibility.EditAvatarImage" = "Edit avatar image";
"Scene.Profile.Accessibility.ShowAvatarImage" = "Show avatar image";
"Scene.Profile.Accessibility.ShowBannerImage" = "Show banner image";
"Scene.Profile.Dashboard.FamiliarFollowers" = "mutuals";
"Scene.Profile.Dashboard.MyFollowers" = "followers";
"Scene.Profile.Dashboard.MyFollowing" = "following";
"Scene.Profile.Dashboard.MyPosts" = "posts";

View File

@ -0,0 +1,21 @@
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
import Accessibility
extension AXCustomContent {
convenience init?(label: String, value: String?) {
if let value, !value.isEmpty {
self.init(label: label, value: value)
} else {
return nil
}
}
convenience init?(label: String, value: (some BinaryInteger)?) {
if let value {
self.init(label: label, value: value.formatted())
} else {
return nil
}
}
}

View File

@ -7,6 +7,7 @@
import Meta
import MastodonLocalization
import Foundation
extension Meta {
public var accessibilityLabel: String? {
@ -25,3 +26,14 @@ extension Meta {
}
}
}
extension MetaContent {
public var accessibilityLabel: String {
return entities.reversed().reduce(string) { string, entity in
if case .emoji(_, let shortcode, _, _) = entity.meta {
return (string as NSString).replacingCharacters(in: entity.range, with: ":" + shortcode + ":")
}
return string
} as String
}
}

View File

@ -9,6 +9,7 @@ import os.log
import UIKit
import Combine
import CoreDataStack
import Meta
import MastodonCore
import MastodonMeta
import MastodonLocalization
@ -23,6 +24,8 @@ extension FamiliarFollowersDashboardView {
@Published var names: [String] = []
@Published var emojis: MastodonContent.Emojis = [:]
@Published var backgroundColor: UIColor?
@Published var label: MetaContent?
}
}
@ -74,11 +77,11 @@ extension FamiliarFollowersDashboardView.ViewModel {
}
.store(in: &disposeBag)
Publishers.CombineLatest(
let label = Publishers.CombineLatest(
$names,
$emojis
)
.sink { names, emojis in
.map { (names, emojis) -> MetaContent in
let content: String = {
guard names.count > 0 else { return " " }
@ -97,13 +100,18 @@ extension FamiliarFollowersDashboardView.ViewModel {
}()
let document = MastodonContent(content: content, emojis: emojis)
do {
let metaContent = try MastodonMetaContent.convert(document: document)
view.descriptionMetaLabel.configure(content: metaContent)
return try MastodonMetaContent.convert(document: document)
} catch {
assertionFailure()
view.descriptionMetaLabel.configure(content: PlaintextMetaContent(string: content))
return PlaintextMetaContent(string: content)
}
}
.store(in: &disposeBag)
label
.sink { [weak self] metaContent in
view.descriptionMetaLabel.configure(content: metaContent)
self?.label = metaContent
}
.store(in: &disposeBag)
}
}

View File

@ -246,5 +246,47 @@ extension ProfileCardView.ViewModel {
view.accessibilityLabel = accessibilityLabel
}
.store(in: &disposeBag)
let statusesContent = $statusesCount
.removeDuplicates()
.map {
AXCustomContent(
label: L10n.Scene.Profile.Dashboard.otherPosts,
value: $0
)
}
let followingContent = $followingCount
.removeDuplicates()
.map {
AXCustomContent(
label: L10n.Scene.Profile.Dashboard.otherFollowing,
value: $0
)
}
let followersContent = $followersCount
.removeDuplicates()
.map {
AXCustomContent(
label: L10n.Scene.Profile.Dashboard.otherFollowers,
value: $0
)
}
let familiarContent = view.familiarFollowersDashboardView.viewModel.$label
.map { $0?.accessibilityLabel }
.removeDuplicates()
.map {
AXCustomContent(
label: L10n.Scene.Profile.Dashboard.familiarFollowers,
value: $0
)
}
Publishers.CombineLatest4(
statusesContent,
followingContent,
followersContent,
familiarContent
).sink { statuses, following, followers, familiar in
view.accessibilityCustomContent = [statuses, following, followers, familiar].compactMap { $0 }
}.store(in: &disposeBag)
}
}

View File

@ -16,7 +16,7 @@ public protocol ProfileCardViewDelegate: AnyObject {
func profileCardView(_ profileCardView: ProfileCardView, familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView)
}
public final class ProfileCardView: UIView {
public final class ProfileCardView: UIView, AXCustomContentProvider {
let logger = Logger(subsystem: "ProfileCardView", category: "View")
@ -27,7 +27,9 @@ public final class ProfileCardView: UIView {
weak var delegate: ProfileCardViewDelegate?
private var _disposeBag = Set<AnyCancellable>()
var disposeBag = Set<AnyCancellable>()
public var accessibilityCustomContent: [AXCustomContent]! = []
let container = UIStackView()
let bannerImageView: UIImageView = {