diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 4a7112553..243d60b9a 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -144,6 +144,7 @@ "tap_to_reveal": "Tap to reveal", "load_embed": "Load Embed", "link_via_user": "%s via %s", + "media_label": "%s, attachment %d of %d", "poll": { "vote": "Vote", "closed": "Closed" diff --git a/Localization/app.json b/Localization/app.json index 4a7112553..243d60b9a 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -144,6 +144,7 @@ "tap_to_reveal": "Tap to reveal", "load_embed": "Load Embed", "link_via_user": "%s via %s", + "media_label": "%s, attachment %d of %d", "poll": { "vote": "Vote", "closed": "Closed" diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index fff18cf38..75f348a0c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -298,6 +298,10 @@ public enum L10n { public static let loadEmbed = L10n.tr("Localizable", "Common.Controls.Status.LoadEmbed", fallback: "Load Embed") /// Tap anywhere to reveal public static let mediaContentWarning = L10n.tr("Localizable", "Common.Controls.Status.MediaContentWarning", fallback: "Tap anywhere to reveal") + /// %@, attachment %d of %d + public static func mediaLabel(_ p1: Any, _ p2: Int, _ p3: Int) -> String { + return L10n.tr("Localizable", "Common.Controls.Status.MediaLabel", String(describing: p1), p2, p3, fallback: "%@, attachment %d of %d") + } /// Sensitive Content public static let sensitiveContent = L10n.tr("Localizable", "Common.Controls.Status.SensitiveContent", fallback: "Sensitive Content") /// Show Post diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index aab9bd6cd..830f887b8 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -117,6 +117,7 @@ Please check your internet connection."; "Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal"; +"Common.Controls.Status.MediaLabel" = "%@, attachment %d of %d"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; "Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift index 1da4e5392..05c8eee14 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift @@ -21,6 +21,8 @@ extension MediaView { public let info: Info public let blurhash: String? + public let index: Int + public let total: Int @Published public var isReveal = true @Published public var previewImage: UIImage? @@ -29,10 +31,14 @@ extension MediaView { public init( info: MediaView.Configuration.Info, - blurhash: String? + blurhash: String?, + index: Int, + total: Int ) { self.info = info self.blurhash = blurhash + self.index = index + self.total = total } public var aspectRadio: CGSize { @@ -186,7 +192,7 @@ extension MediaView { let status = status.reblog ?? status let attachments = status.attachments - let configurations = attachments.map { attachment -> MediaView.Configuration in + let configurations = attachments.enumerated().map { (idx, attachment) -> MediaView.Configuration in let configuration: MediaView.Configuration = { switch attachment.kind { case .image: @@ -197,25 +203,33 @@ extension MediaView { ) return .init( info: .image(info: info), - blurhash: attachment.blurhash + blurhash: attachment.blurhash, + index: idx, + total: attachments.count ) case .video: let info = videoInfo(from: attachment) return .init( info: .video(info: info), - blurhash: attachment.blurhash + blurhash: attachment.blurhash, + index: idx, + total: attachments.count ) case .gifv: let info = videoInfo(from: attachment) return .init( info: .gif(info: info), - blurhash: attachment.blurhash + blurhash: attachment.blurhash, + index: idx, + total: attachments.count ) case .audio: let info = videoInfo(from: attachment) return .init( info: .video(info: info), - blurhash: attachment.blurhash + blurhash: attachment.blurhash, + index: idx, + total: attachments.count ) } // end switch }() diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 814e48e6a..1b471d34a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -11,6 +11,7 @@ import UIKit import Combine import AlamofireImage import SwiftUI +import MastodonLocalization public final class MediaView: UIView { @@ -168,12 +169,9 @@ extension MediaView { } .store(in: &configuration.disposeBag) - accessibilityLabel = info.altDescription - if #available(iOS 15.0, *) { - altViewController.rootView.altDescription = info.altDescription - } + bindAlt(configuration: configuration, altDescription: info.altDescription) } - + private func layoutGIF() { // use view controller as View here playerViewController.view.translatesAutoresizingMaskIntoConstraints = false @@ -195,10 +193,7 @@ extension MediaView { // auto play for GIF player.play() - accessibilityLabel = info.altDescription - if #available(iOS 15.0, *) { - altViewController.rootView.altDescription = info.altDescription - } + bindAlt(configuration: configuration, altDescription: info.altDescription) } private func layoutVideo() { @@ -223,6 +218,21 @@ extension MediaView { bindImage(configuration: configuration, info: imageInfo) } + private func bindAlt(configuration: Configuration, altDescription: String?) { + if configuration.total > 1 { + accessibilityLabel = L10n.Common.Controls.Status.mediaLabel( + altDescription ?? "", + configuration.index + 1, + configuration.total + ) + } else { + accessibilityLabel = altDescription + } + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = altDescription + } + } + private func layoutBlurhash() { blurhashImageView.translatesAutoresizingMaskIntoConstraints = false container.addSubview(blurhashImageView)