Updated accessibility ids as per documentation

pull/894/head
Morgan Pretty 1 year ago
parent 22e65c7224
commit b3f57bc677

@ -168,8 +168,6 @@
7BFD1A972747689000FB91B9 /* Session-Turn-Server in Resources */ = {isa = PBXBuildFile; fileRef = 7BFD1A962747689000FB91B9 /* Session-Turn-Server */; };
9422EE2B2B8C3A97004C740D /* String+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9422EE2A2B8C3A97004C740D /* String+Utilities.swift */; };
943C6D822B75E061004ACE64 /* Message+DisappearingMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943C6D812B75E061004ACE64 /* Message+DisappearingMessages.swift */; };
9593A1E796C9E6BE2352EA6F /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8B0BA5257C58DC6FF797278 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionSnodeKit.framework */; };
99978E3F7A80275823CA9014 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29E827FDF6C1032BB985740C /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework */; };
A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; };
A163E8AB16F3F6AA0094D68B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A163E8AA16F3F6A90094D68B /* Security.framework */; };
A1C32D5017A06538000A904E /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C32D4F17A06537000A904E /* AddressBookUI.framework */; };
@ -1407,16 +1405,9 @@
8987AF66FCCD593D38330F7F /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8F514E455DFEA2D1DE663AD0 /* Pods_GlobalDependencies_SessionUIKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_SessionUIKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8FF6E201CDC2C275F9AD4E5F /* Pods-GlobalDependencies-Session-SessionTests.app_store_release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-Session-SessionTests.app_store_release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-Session-SessionTests/Pods-GlobalDependencies-Session-SessionTests.app_store_release.xcconfig"; sourceTree = "<group>"; };
9D7B6CC77991D7A398580039 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; sourceTree = "<group>"; };
8448EFF76CD3CA5B2283B8A0 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.debug.xcconfig"; sourceTree = "<group>"; };
847091A12D82E41B1EBB8FB3 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.debug.xcconfig"; sourceTree = "<group>"; };
8603226ED1C6F61F1F2D3734 /* Pods-GlobalDependencies-Session.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-Session.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-Session/Pods-GlobalDependencies-Session.app store release.xcconfig"; sourceTree = "<group>"; };
8727C47348B6EFA767EE583A /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig"; sourceTree = "<group>"; };
8E946CB54A221018E23599DE /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig"; sourceTree = "<group>"; };
92E8569C96285EE3CDB5960D /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
93359C81CF2660040B7CD106 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9422EE2A2B8C3A97004C740D /* String+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Utilities.swift"; sourceTree = "<group>"; };
943C6D812B75E061004ACE64 /* Message+DisappearingMessages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Message+DisappearingMessages.swift"; sourceTree = "<group>"; };
9D7B6CC77991D7A398580039 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; sourceTree = "<group>"; };
A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
A13597801E7E865C4B5C4188 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A163E8AA16F3F6A90094D68B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };

@ -12,6 +12,15 @@ import SessionUtilitiesKit
import SignalUtilitiesKit
class EditGroupViewModel: SessionTableViewModel, NavigatableStateHolder, EditableStateHolder, ObservableTableSource {
private static let minVersionBannerInfo: InfoBanner.Info = InfoBanner.Info(
font: .systemFont(ofSize: Values.verySmallFontSize),
message: "GROUP_MEMBERS_MIN_VERSION".localized(),
icon: .none,
tintColor: .black,
backgroundColor: .warning,
accessibility: Accessibility(identifier: "Version warning banner")
)
public let dependencies: Dependencies
public let navigatableState: NavigatableState = NavigatableState()
public let editableState: EditableState<TableItem> = EditableState()
@ -94,6 +103,8 @@ class EditGroupViewModel: SessionTableViewModel, NavigatableStateHolder, Editabl
let title: String = "EDIT_GROUP_ACTION".localized()
var bannerInfo: AnyPublisher<InfoBanner.Info?, Never> { Just(EditGroupViewModel.minVersionBannerInfo).eraseToAnyPublisher() }
lazy var observation: TargetObservation = ObservationBuilder
.databaseObservation(self) { [dependencies, threadId, userSessionId] db -> State in
guard let group: ClosedGroup = try ClosedGroup.fetchOne(db, id: threadId) else {
@ -343,7 +354,7 @@ class EditGroupViewModel: SessionTableViewModel, NavigatableStateHolder, Editabl
memberInfo.value.statusDescription,
font: .subtitle,
accessibility: Accessibility(
identifier: "Status"
identifier: "Contact status"
)
)),
trailingAccessory: {
@ -354,8 +365,12 @@ class EditGroupViewModel: SessionTableViewModel, NavigatableStateHolder, Editabl
title: "context_menu_resend".localized(),
isSelected: selectedIdsSubject.value.contains(memberInfo.profileId),
labelAccessibility: Accessibility(
identifier: "Resend invite",
label: "Resend invite"
identifier: "Resend invite button",
label: "Resend invite button"
),
radioAccessibility: Accessibility(
identifier: "Select contact",
label: "Select contact"
)
)
@ -738,6 +753,7 @@ class EditGroupViewModel: SessionTableViewModel, NavigatableStateHolder, Editabl
SessionTableViewController(
viewModel: UserListViewModel<Contact>(
title: "GROUP_ACTION_INVITE_CONTACTS".localized(),
infoBanner: EditGroupViewModel.minVersionBannerInfo,
emptyState: "GROUP_ACTION_INVITE_EMPTY_STATE".localized(),
showProfileIcons: true,
request: SQLRequest("""

@ -289,7 +289,7 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers
let text: String = viewModel.threadData.emptyStateText
let result: UILabel = UILabel()
result.isAccessibilityElement = true
result.accessibilityIdentifier = "Empty conversation"
result.accessibilityIdentifier = "Control message"
result.translatesAutoresizingMaskIntoConstraints = false
result.font = .systemFont(ofSize: Values.verySmallFontSize)
result.attributedText = NSAttributedString(string: text)
@ -420,6 +420,7 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers
private lazy var messageRequestBlockButton: UIButton = {
let result: UIButton = UIButton()
result.accessibilityIdentifier = "Block"
result.accessibilityLabel = "Block message request"
result.translatesAutoresizingMaskIntoConstraints = false
result.clipsToBounds = true

@ -35,6 +35,30 @@ final class InfoBanner: UIView {
let height: CGFloat?
let onTap: (() -> Void)?
static var empty: Info = Info(font: .systemFont(ofSize: Values.smallFontSize), message: "")
public init(
font: UIFont,
message: String,
icon: Icon = .none,
tintColor: ThemeValue = .black,
backgroundColor: ThemeValue = .primary,
accessibility: Accessibility? = nil,
labelAccessibility: Accessibility? = nil,
height: CGFloat? = nil,
onTap: (() -> Void)? = nil
) {
self.font = font
self.message = message
self.icon = icon
self.tintColor = tintColor
self.backgroundColor = backgroundColor
self.accessibility = accessibility
self.labelAccessibility = labelAccessibility
self.height = height
self.onTap = onTap
}
func with(
font: UIFont? = nil,
message: String? = nil,
@ -94,8 +118,8 @@ final class InfoBanner: UIView {
return result
}()
private lazy var leftIconImageView: UIImageView = {
let result: UIImageView = UIImageView()
private lazy var leftIconPadding: UIView = {
let result: UIView = UIView()
result.set(.width, to: 18)
result.set(.height, to: 18)
result.isHidden = true
@ -134,7 +158,7 @@ final class InfoBanner: UIView {
addSubview(stackView)
stackView.addArrangedSubview(leftIconImageView)
stackView.addArrangedSubview(leftIconPadding)
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(rightIconImageView)
@ -143,12 +167,7 @@ final class InfoBanner: UIView {
stackView.pin(.leading, to: .leading, of: self, withInset: Values.mediumSpacing)
stackView.pin(.trailing, to: .trailing, of: self, withInset: -Values.mediumSpacing)
switch info.height {
case .some(let fixedHeight): self.heightConstraint = self.set(.height, to: fixedHeight)
case .none: self.heightConstraint?.isActive = false
}
self.update(info)
self.update(with: info)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(bannerTapped))
self.addGestureRecognizer(tapGestureRecognizer)
@ -170,26 +189,6 @@ final class InfoBanner: UIView {
// MARK: - Update
private func update(_ info: InfoBanner.Info) {
self.info = info
themeBackgroundColor = info.backgroundColor
isAccessibilityElement = (info.accessibility != nil)
accessibilityIdentifier = info.accessibility?.identifier
accessibilityLabel = info.accessibility?.label
label.font = info.font
label.text = info.message
label.themeTextColor = info.tintColor
label.accessibilityIdentifier = info.labelAccessibility?.identifier
label.accessibilityLabel = info.labelAccessibility?.label
leftIconImageView.image = info.icon.image
leftIconImageView.isHidden = (info.icon != .none)
leftIconImageView.themeTintColor = info.tintColor
rightIconImageView.isHidden = (info.icon != .none)
rightIconImageView.themeTintColor = info.tintColor
}
public func update(
font: UIFont? = nil,
message: String? = nil,
@ -204,7 +203,7 @@ final class InfoBanner: UIView {
guard let currentInfo: Info = self.info else { return }
self.update(
currentInfo.with(
with: currentInfo.with(
font: font,
message: message,
icon: icon,
@ -217,4 +216,28 @@ final class InfoBanner: UIView {
)
)
}
public func update(with info: InfoBanner.Info) {
self.info = info
self.heightConstraint?.isActive = false // Calling 'set' below will enable it
switch info.height {
case .some(let fixedHeight): self.heightConstraint = self.set(.height, to: fixedHeight)
case .none: break
}
themeBackgroundColor = info.backgroundColor
isAccessibilityElement = (info.accessibility != nil)
accessibilityIdentifier = info.accessibility?.identifier
accessibilityLabel = info.accessibility?.label
label.font = info.font
label.text = info.message
label.themeTextColor = info.tintColor
label.accessibilityIdentifier = info.labelAccessibility?.identifier
label.accessibilityLabel = info.labelAccessibility?.label
rightIconImageView.image = info.icon.image
rightIconImageView.isHidden = (info.icon == .none)
rightIconImageView.themeTintColor = info.tintColor
}
}

@ -212,7 +212,7 @@ class MessageRequestsViewModel: SessionTableViewModel, NavigatableStateHolder, O
),
confirmTitle: "MESSAGE_REQUESTS_CLEAR_ALL_CONFIRMATION_ACTON".localized(),
confirmAccessibility: Accessibility(
identifier: "Clear all"
identifier: "Confirm clear"
),
confirmStyle: .danger,
cancelStyle: .alert_text,

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1054,3 +1054,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1054,3 +1054,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1059,3 +1059,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -1053,3 +1053,5 @@ The point that a message will disappear in a disappearing message update message
/* A message indicating how the disappearing messages setting applies in a one-to-one conversation for legacy mode */
"DISAPPERING_MESSAGES_SUBTITLE_LEGACY" = "This setting applies to everyone in this conversation.";
"GROUP_MEMBERS_MIN_VERSION" = "Users must have at least Session version {version} to see invites";

@ -526,19 +526,19 @@ class SettingsViewModel: SessionTableViewModel, NavigationItemSource, Navigatabl
icon: .rightPlus,
style: .circular,
accessibility: Accessibility(
identifier: "Upload image",
label: "Upload image"
identifier: "Upload",
label: "Upload"
),
onClick: { [weak self] in self?.showPhotoLibraryForAvatar() }
),
confirmTitle: "update_profile_modal_save".localized(),
confirmAccessibility: Accessibility(
identifier: "Save"
identifier: "Save button"
),
confirmEnabled: false,
cancelTitle: "update_profile_modal_remove".localized(),
cancelAccessibility: Accessibility(
identifier: "Remove"
identifier: "Remove button"
),
cancelEnabled: (existingImageData != nil),
hasCloseButton: true,

@ -33,6 +33,25 @@ class SessionTableViewController<ViewModel>: BaseVC, UITableViewDataSource, UITa
private lazy var titleView: SessionTableViewTitleView = SessionTableViewTitleView()
private lazy var contentStackView: UIStackView = {
let result: UIStackView = UIStackView(arrangedSubviews: [
infoBanner,
tableView
])
result.axis = .vertical
result.alignment = .fill
result.distribution = .fill
return result
}()
private lazy var infoBanner: InfoBanner = {
let result: InfoBanner = InfoBanner(info: .empty)
result.isHidden = true
return result
}()
private lazy var tableView: UITableView = {
let result: UITableView = UITableView()
result.translatesAutoresizingMaskIntoConstraints = false
@ -132,7 +151,7 @@ class SessionTableViewController<ViewModel>: BaseVC, UITableViewDataSource, UITa
titleView.update(title: self.viewModel.title, subtitle: self.viewModel.subtitle)
view.themeBackgroundColor = .backgroundPrimary
view.addSubview(tableView)
view.addSubview(contentStackView)
view.addSubview(initialLoadLabel)
view.addSubview(emptyStateLabel)
view.addSubview(fadeView)
@ -186,7 +205,7 @@ class SessionTableViewController<ViewModel>: BaseVC, UITableViewDataSource, UITa
}
private func setupLayout() {
tableView.pin(to: view)
contentStackView.pin(to: view)
initialLoadLabel.pin(.top, to: .top, of: self.view, withInset: Values.massiveSpacing)
initialLoadLabel.pin(.leading, to: .leading, of: self.view, withInset: Values.mediumSpacing)
@ -373,6 +392,19 @@ class SessionTableViewController<ViewModel>: BaseVC, UITableViewDataSource, UITa
}
.store(in: &disposables)
viewModel.bannerInfo
.receive(on: DispatchQueue.main)
.sink { [weak self] info in
switch info {
case .some(let info):
self?.infoBanner.update(with: info)
self?.infoBanner.isHidden = false
case .none: self?.infoBanner.isHidden = true
}
}
.store(in: &disposables)
viewModel.emptyStateTextPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] text in

@ -15,6 +15,7 @@ protocol SessionTableViewModel: AnyObject, SectionedTableData {
var subtitle: String? { get }
var initialLoadMessage: String? { get }
var cellType: SessionTableViewCellType { get }
var bannerInfo: AnyPublisher<InfoBanner.Info?, Never> { get }
var emptyStateTextPublisher: AnyPublisher<String?, Never> { get }
var state: TableDataState<Section, TableItem> { get }
var footerView: AnyPublisher<UIView?, Never> { get }
@ -31,6 +32,7 @@ extension SessionTableViewModel {
var subtitle: String? { nil }
var initialLoadMessage: String? { nil }
var cellType: SessionTableViewCellType { .general }
var bannerInfo: AnyPublisher<InfoBanner.Info?, Never> { Just(nil).eraseToAnyPublisher() }
var emptyStateTextPublisher: AnyPublisher<String?, Never> { Just(nil).eraseToAnyPublisher() }
var tableData: [SectionModel] { state.tableData }
var footerView: AnyPublisher<UIView?, Never> { Just(nil).eraseToAnyPublisher() }

@ -116,8 +116,8 @@ public extension SessionCell.Accessory {
isSelected: Bool? = nil,
liveIsSelected: (() -> Bool)? = nil,
wasSavedSelection: Bool = false,
accessibility: Accessibility? = nil,
labelAccessibility: Accessibility? = nil
labelAccessibility: Accessibility? = nil,
radioAccessibility: Accessibility? = nil
) -> SessionCell.Accessory {
return SessionCell.AccessoryConfig.HighlightingBackgroundLabelAndRadio(
title: title,
@ -125,8 +125,8 @@ public extension SessionCell.Accessory {
initialIsSelected: ((isSelected ?? liveIsSelected?()) ?? false),
liveIsSelected: (liveIsSelected ?? { (isSelected ?? false) }),
wasSavedSelection: wasSavedSelection,
accessibility: accessibility,
labelAccessibility: labelAccessibility
labelAccessibility: labelAccessibility,
radioAccessibility: radioAccessibility
)
}
@ -494,8 +494,8 @@ public extension SessionCell.AccessoryConfig {
initialIsSelected: Bool,
liveIsSelected: @escaping () -> Bool,
wasSavedSelection: Bool,
accessibility: Accessibility?,
labelAccessibility: Accessibility?
labelAccessibility: Accessibility?,
radioAccessibility: Accessibility?
) {
self.title = title
self.size = radioSize
@ -504,7 +504,7 @@ public extension SessionCell.AccessoryConfig {
self.wasSavedSelection = wasSavedSelection
self.labelAccessibility = labelAccessibility
super.init(accessibility: accessibility)
super.init(accessibility: radioAccessibility)
}
// MARK: - Conformance

@ -18,6 +18,7 @@ class UserListViewModel<T: ProfileAssociated & FetchableRecord>: SessionTableVie
private let selectedUsersSubject: CurrentValueSubject<Set<WithProfile<T>>, Never> = CurrentValueSubject([])
public let title: String
public let infoBanner: InfoBanner.Info?
public let emptyState: String?
private let showProfileIcons: Bool
private let request: (any FetchRequest<T>)
@ -29,6 +30,7 @@ class UserListViewModel<T: ProfileAssociated & FetchableRecord>: SessionTableVie
init(
title: String,
infoBanner: InfoBanner.Info? = nil,
emptyState: String? = nil,
showProfileIcons: Bool,
request: (any FetchRequest<T>),
@ -39,6 +41,7 @@ class UserListViewModel<T: ProfileAssociated & FetchableRecord>: SessionTableVie
) {
self.dependencies = dependencies
self.title = title
self.infoBanner = infoBanner
self.emptyState = emptyState
self.showProfileIcons = showProfileIcons
self.request = request
@ -79,6 +82,7 @@ class UserListViewModel<T: ProfileAssociated & FetchableRecord>: SessionTableVie
}
}
var bannerInfo: AnyPublisher<InfoBanner.Info?, Never> { Just(infoBanner).eraseToAnyPublisher() }
var emptyStateTextPublisher: AnyPublisher<String?, Never> { Just(emptyState).eraseToAnyPublisher() }
lazy var observation: TargetObservation = ObservationBuilder

@ -95,6 +95,7 @@ public extension UIContextualAction {
),
themeTintColor: .white,
themeBackgroundColor: .conversationButton_swipeRead, // Always Custom
accessibility: Accessibility(identifier: (isUnread ? "Mark Read button" : "Mark Unread button")),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -123,6 +124,7 @@ public extension UIContextualAction {
icon: UIImage(systemName: "eye.slash"),
themeTintColor: .white,
themeBackgroundColor: themeBackgroundColor,
accessibility: Accessibility(identifier: "Hide button"),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -198,6 +200,9 @@ public extension UIContextualAction {
),
themeTintColor: .white,
themeBackgroundColor: .conversationButton_swipeTertiary, // Always Tertiary
accessibility: Accessibility(
identifier: (threadViewModel.threadPinnedPriority > 0 ? "Pin button" : "Unpin button")
),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -239,6 +244,9 @@ public extension UIContextualAction {
iconHeight: Values.mediumFontSize,
themeTintColor: .white,
themeBackgroundColor: themeBackgroundColor,
accessibility: Accessibility(
identifier: (threadViewModel.threadMutedUntilTimestamp == nil ? "Mute button" : "Unmute button")
),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -286,6 +294,7 @@ public extension UIContextualAction {
iconHeight: Values.mediumFontSize,
themeTintColor: .white,
themeBackgroundColor: themeBackgroundColor,
accessibility: Accessibility(identifier: "Block button"),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -403,7 +412,7 @@ public extension UIContextualAction {
body: .text(bodyText),
confirmTitle: "BLOCK_LIST_BLOCK_BUTTON".localized(),
confirmAccessibility: Accessibility(
identifier: "Block"
identifier: "Confirm block"
),
confirmStyle: .danger,
cancelStyle: .alert_text,
@ -428,6 +437,7 @@ public extension UIContextualAction {
iconHeight: Values.mediumFontSize,
themeTintColor: .white,
themeBackgroundColor: themeBackgroundColor,
accessibility: Accessibility(identifier: "Leave button"),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -502,6 +512,7 @@ public extension UIContextualAction {
iconHeight: Values.mediumFontSize,
themeTintColor: .white,
themeBackgroundColor: themeBackgroundColor,
accessibility: Accessibility(identifier: "Delete button"),
side: side,
actionIndex: targetIndex,
indexPath: indexPath,
@ -573,7 +584,7 @@ public extension UIContextualAction {
body: .attributedText(confirmationModalExplanation),
confirmTitle: "TXT_DELETE_TITLE".localized(),
confirmAccessibility: Accessibility(
identifier: "Delete"
identifier: "Confirm delete"
),
confirmStyle: .danger,
cancelStyle: .alert_text,

@ -457,7 +457,7 @@ public extension ConfirmationModal {
confirmEnabled: Bool = true,
cancelTitle: String = "TXT_CANCEL_TITLE".localized(),
cancelAccessibility: Accessibility? = Accessibility(
identifier: "Cancel"
identifier: "Cancel button"
),
cancelStyle: ThemeValue = .danger,
cancelEnabled: Bool = true,

@ -4,7 +4,12 @@ import UIKit
import SessionUtilitiesKit
public extension UIContextualAction {
private static var lookupMap: Atomic<[Int: [String: [Int: ThemeValue]]]> = Atomic([:])
private static var lookupMap: Atomic<[Int: [String: [Int: ActionInfo]]]> = Atomic([:])
private struct ActionInfo {
let themeTintColor: ThemeValue
let accessibility: Accessibility?
}
enum Side: Int {
case leading
@ -30,6 +35,7 @@ public extension UIContextualAction {
iconHeight: CGFloat = Values.mediumFontSize,
themeTintColor: ThemeValue = .white,
themeBackgroundColor: ThemeValue,
accessibility: Accessibility? = nil,
side: Side,
actionIndex: Int,
indexPath: IndexPath,
@ -46,13 +52,20 @@ public extension UIContextualAction {
)?
.withRenderingMode(.alwaysTemplate)
self.themeBackgroundColor = themeBackgroundColor
self.accessibilityLabel = accessibility?.label
UIContextualAction.lookupMap.mutate {
$0[tableView.hashValue] = ($0[tableView.hashValue] ?? [:])
.setting(
side.key(for: indexPath),
(($0[tableView.hashValue] ?? [:])[side.key(for: indexPath)] ?? [:])
.setting(actionIndex, themeTintColor)
.setting(
actionIndex,
ActionInfo(
themeTintColor: themeTintColor,
accessibility: accessibility
)
)
)
}
}
@ -139,7 +152,7 @@ public extension UIContextualAction {
.filter({ $0 != targetCell })
.first,
let side: Side = Side(for: targetSuperview),
let themeMap: [Int: ThemeValue] = UIContextualAction.lookupMap.wrappedValue
let themeMap: [Int: ActionInfo] = UIContextualAction.lookupMap.wrappedValue
.getting(tableView.hashValue)?
.getting(side.key(for: indexPath)),
targetSuperview.subviews.count == themeMap.count
@ -152,9 +165,10 @@ public extension UIContextualAction {
// Set the imageView and background colours (so they change correctly when the theme changes)
targetViews.enumerated().forEach { index, targetView in
guard let themeTintColor: ThemeValue = themeMap[index] else { return }
guard let actionInfo: ActionInfo = themeMap[index] else { return }
targetView.themeTintColor = themeTintColor
targetView.themeTintColor = actionInfo.themeTintColor
targetView.accessibilityIdentifier = actionInfo.accessibility?.identifier
}
}

Loading…
Cancel
Save