Added some accessibility info

Fixed an issue where the Display Picture update modal wouldn't rendering animated images actually animating
pull/751/head
Morgan Pretty 1 year ago
parent 9799297e15
commit 2053b6b0cd

@ -3,6 +3,7 @@
import Foundation import Foundation
import Combine import Combine
import GRDB import GRDB
import YYImage
import DifferenceKit import DifferenceKit
import SessionUIKit import SessionUIKit
import SessionMessagingKit import SessionMessagingKit
@ -155,9 +156,7 @@ class SettingsViewModel: SessionTableViewModel<SettingsViewModel.NavButton, Sett
} }
override var rightNavItems: AnyPublisher<[NavItem]?, Never> { override var rightNavItems: AnyPublisher<[NavItem]?, Never> {
let userSessionId: String = self.userSessionId navState
return navState
.map { [weak self] navState -> [NavItem] in .map { [weak self] navState -> [NavItem] in
switch navState { switch navState {
case .standard: case .standard:
@ -488,21 +487,31 @@ class SettingsViewModel: SessionTableViewModel<SettingsViewModel.NavButton, Sett
private func updateProfilePicture(currentFileName: String?) { private func updateProfilePicture(currentFileName: String?) {
let existingDisplayName: String = self.oldDisplayName let existingDisplayName: String = self.oldDisplayName
let existingImage: UIImage? = currentFileName let existingImageData: (image: UIImage?, animatedImage: YYImage?)? = currentFileName
.map { ProfileManager.loadProfileData(with: $0) } .map { ProfileManager.loadProfileData(with: $0) }
.map { UIImage(data: $0) } .map { imageData in
switch imageData.guessedImageFormat {
case .gif, .webp: return (nil, YYImage(data: imageData))
default: return (UIImage(data: imageData), nil)
}
}
let editProfilePictureModalInfo: ConfirmationModal.Info = ConfirmationModal.Info( let editProfilePictureModalInfo: ConfirmationModal.Info = ConfirmationModal.Info(
title: "update_profile_modal_title".localized(), title: "update_profile_modal_title".localized(),
body: .image( body: .image(
placeholder: UIImage(named: "profile_placeholder"), placeholder: UIImage(named: "profile_placeholder"),
value: existingImage, value: existingImageData?.image,
animatedValue: existingImageData?.animatedImage,
style: .circular, style: .circular,
accessibility: Accessibility(
identifier: "Image picker",
label: "Image picker"
),
onClick: { [weak self] in self?.showPhotoLibraryForAvatar() } onClick: { [weak self] in self?.showPhotoLibraryForAvatar() }
), ),
confirmTitle: "update_profile_modal_upload".localized(), confirmTitle: "update_profile_modal_upload".localized(),
confirmEnabled: false, confirmEnabled: false,
cancelTitle: "update_profile_modal_remove".localized(), cancelTitle: "update_profile_modal_remove".localized(),
cancelEnabled: (existingImage != nil), cancelEnabled: (existingImageData != nil),
hasCloseButton: true, hasCloseButton: true,
dismissOnConfirm: false, dismissOnConfirm: false,
onConfirm: { modal in modal.close() }, onConfirm: { modal in modal.close() },
@ -535,11 +544,20 @@ class SettingsViewModel: SessionTableViewModel<SettingsViewModel.NavButton, Sett
value: { value: {
switch avatarUpdate { switch avatarUpdate {
case .uploadImage(let image): return image case .uploadImage(let image): return image
case .uploadFilePath(let filePath): return UIImage(contentsOfFile: filePath) default: return nil
}
}(),
animatedValue: {
switch avatarUpdate {
case .uploadFilePath(let filePath): return YYImage(contentsOfFile: filePath)
default: return nil default: return nil
} }
}(), }(),
style: .circular, style: .circular,
accessibility: Accessibility(
identifier: "Image picker",
label: "Image picker"
),
onClick: { [weak self] in self?.showPhotoLibraryForAvatar() } onClick: { [weak self] in self?.showPhotoLibraryForAvatar() }
), ),
confirmEnabled: true, confirmEnabled: true,

@ -10,8 +10,8 @@ import SessionUtilitiesKit
public extension Features { public extension Features {
static func useSharedUtilForUserConfig(_ db: Database? = nil) -> Bool { static func useSharedUtilForUserConfig(_ db: Database? = nil) -> Bool {
// TODO: Need to set this timestamp to the correct date // TODO: Need to set this timestamp to the correct date (currently start of 2030)
guard Date().timeIntervalSince1970 < 1893456000 else { return true } // guard Date().timeIntervalSince1970 < 1893456000 else { return true }
guard !SessionUtil.hasCheckedMigrationsCompleted.wrappedValue else { guard !SessionUtil.hasCheckedMigrationsCompleted.wrappedValue else {
return SessionUtil.userConfigsEnabledIgnoringFeatureFlag return SessionUtil.userConfigsEnabledIgnoringFeatureFlag
} }

@ -1,6 +1,7 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import UIKit import UIKit
import YYImage
import SessionUtilitiesKit import SessionUtilitiesKit
// FIXME: Refactor as part of the Groups Rebuild // FIXME: Refactor as part of the Groups Rebuild
@ -41,6 +42,12 @@ public class ConfirmationModal: Modal {
let result: UIView = UIView() let result: UIView = UIView()
result.isHidden = true result.isHidden = true
let gestureRecogniser: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(imageViewTapped)
)
result.addGestureRecognizer(gestureRecogniser)
return result return result
}() }()
@ -50,6 +57,18 @@ public class ConfirmationModal: Modal {
result.contentMode = .scaleAspectFill result.contentMode = .scaleAspectFill
result.set(.width, to: ConfirmationModal.imageSize) result.set(.width, to: ConfirmationModal.imageSize)
result.set(.height, to: ConfirmationModal.imageSize) result.set(.height, to: ConfirmationModal.imageSize)
result.isHidden = true
return result
}()
private lazy var animatedImageView: YYAnimatedImageView = {
let result: YYAnimatedImageView = YYAnimatedImageView()
result.clipsToBounds = true
result.contentMode = .scaleAspectFill
result.set(.width, to: ConfirmationModal.imageSize)
result.set(.height, to: ConfirmationModal.imageSize)
result.isHidden = true
return result return result
}() }()
@ -84,12 +103,6 @@ public class ConfirmationModal: Modal {
right: Values.largeSpacing right: Values.largeSpacing
) )
let gestureRecogniser: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(bodyTapped)
)
result.addGestureRecognizer(gestureRecogniser)
return result return result
}() }()
@ -115,6 +128,9 @@ public class ConfirmationModal: Modal {
bottom: 6, bottom: 6,
right: 6 right: 6
) )
result.isAccessibilityElement = true
result.accessibilityIdentifier = "Close button"
result.accessibilityLabel = "Close button"
result.set(.width, to: ConfirmationModal.closeSize) result.set(.width, to: ConfirmationModal.closeSize)
result.set(.height, to: ConfirmationModal.closeSize) result.set(.height, to: ConfirmationModal.closeSize)
result.addTarget(self, action: #selector(close), for: .touchUpInside) result.addTarget(self, action: #selector(close), for: .touchUpInside)
@ -146,6 +162,11 @@ public class ConfirmationModal: Modal {
imageView.pin(.top, to: .top, of: imageViewContainer, withInset: 15) imageView.pin(.top, to: .top, of: imageViewContainer, withInset: 15)
imageView.pin(.bottom, to: .bottom, of: imageViewContainer, withInset: -15) imageView.pin(.bottom, to: .bottom, of: imageViewContainer, withInset: -15)
imageViewContainer.addSubview(animatedImageView)
animatedImageView.center(.horizontal, in: imageViewContainer)
animatedImageView.pin(.top, to: .top, of: imageViewContainer, withInset: 15)
animatedImageView.pin(.bottom, to: .bottom, of: imageViewContainer, withInset: -15)
mainStackView.pin(to: contentView) mainStackView.pin(to: contentView)
closeButton.pin(.top, to: .top, of: contentView, withInset: 8) closeButton.pin(.top, to: .top, of: contentView, withInset: 8)
closeButton.pin(.right, to: .right, of: contentView, withInset: -8) closeButton.pin(.right, to: .right, of: contentView, withInset: -8)
@ -185,15 +206,32 @@ public class ConfirmationModal: Modal {
explanationLabel.attributedText = attributedText explanationLabel.attributedText = attributedText
explanationLabel.isHidden = false explanationLabel.isHidden = false
case .image(let placeholder, let value, let style, let onClick): case .image(let placeholder, let value, let animatedValue, let style, let accessibility, let onClick):
imageViewContainer.isAccessibilityElement = (accessibility != nil)
imageViewContainer.accessibilityIdentifier = accessibility?.identifier
imageViewContainer.accessibilityLabel = accessibility?.label
mainStackView.spacing = 0 mainStackView.spacing = 0
imageView.image = (value ?? placeholder)
imageView.layer.cornerRadius = (style == .circular ?
(ConfirmationModal.imageSize / 2) :
0
)
imageViewContainer.isHidden = false imageViewContainer.isHidden = false
internalOnBodyTap = onClick internalOnBodyTap = onClick
if let animatedValue: YYImage = animatedValue {
imageView.isHidden = true
animatedImageView.image = animatedValue
animatedImageView.isHidden = false
animatedImageView.layer.cornerRadius = (style == .circular ?
(ConfirmationModal.imageSize / 2) :
0
)
}
else {
animatedImageView.isHidden = true
imageView.image = (value ?? placeholder)
imageView.isHidden = false
imageView.layer.cornerRadius = (style == .circular ?
(ConfirmationModal.imageSize / 2) :
0
)
}
} }
confirmButton.accessibilityLabel = info.confirmAccessibility?.label confirmButton.accessibilityLabel = info.confirmAccessibility?.label
@ -219,7 +257,7 @@ public class ConfirmationModal: Modal {
// MARK: - Interaction // MARK: - Interaction
@objc private func bodyTapped() { @objc private func imageViewTapped() {
internalOnBodyTap?() internalOnBodyTap?()
} }
@ -407,7 +445,9 @@ public extension ConfirmationModal.Info {
case image( case image(
placeholder: UIImage?, placeholder: UIImage?,
value: UIImage?, value: UIImage?,
animatedValue: YYImage?,
style: ImageStyle, style: ImageStyle,
accessibility: Accessibility?,
onClick: (() -> ()) onClick: (() -> ())
) )
@ -431,11 +471,13 @@ public extension ConfirmationModal.Info {
// lhsOptions.map { "\($0.0)-\($0.1)" } == rhsValue.map { "\($0.0)-\($0.1)" } // lhsOptions.map { "\($0.0)-\($0.1)" } == rhsValue.map { "\($0.0)-\($0.1)" }
// ) // )
case (.image(let lhsPlaceholder, let lhsValue, let lhsStyle, _), .image(let rhsPlaceholder, let rhsValue, let rhsStyle, _)): case (.image(let lhsPlaceholder, let lhsValue, let lhsAnimatedValue, let lhsStyle, let lhsAccessibility, _), .image(let rhsPlaceholder, let rhsValue, let rhsAnimatedValue, let rhsStyle, let rhsAccessibility, _)):
return ( return (
lhsPlaceholder == rhsPlaceholder && lhsPlaceholder == rhsPlaceholder &&
lhsValue == rhsValue && lhsValue == rhsValue &&
lhsStyle == rhsStyle lhsAnimatedValue == rhsAnimatedValue &&
lhsStyle == rhsStyle &&
lhsAccessibility == rhsAccessibility
) )
default: return false default: return false
@ -448,10 +490,12 @@ public extension ConfirmationModal.Info {
case .text(let text): text.hash(into: &hasher) case .text(let text): text.hash(into: &hasher)
case .attributedText(let text): text.hash(into: &hasher) case .attributedText(let text): text.hash(into: &hasher)
case .image(let placeholder, let value, let style, _): case .image(let placeholder, let value, let animatedValue, let style, let accessibility, _):
placeholder.hash(into: &hasher) placeholder.hash(into: &hasher)
value.hash(into: &hasher) value.hash(into: &hasher)
animatedValue.hash(into: &hasher)
style.hash(into: &hasher) style.hash(into: &hasher)
accessibility.hash(into: &hasher)
} }
} }
} }

Loading…
Cancel
Save