From d7f9488c4fd337b00655f8c9a55b92815451e12f Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 6 Jun 2022 12:54:01 +0200 Subject: [PATCH 001/733] Ignore warnings from external Pods. --- Podfile | 2 ++ Podfile.lock | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Podfile b/Podfile index a64cd0e55..8a81da6e1 100644 --- a/Podfile +++ b/Podfile @@ -1,5 +1,7 @@ platform :ios, '14.0' +inhibit_all_warnings! + target 'Mastodon' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! diff --git a/Podfile.lock b/Podfile.lock index 629a48a87..87bdfa910 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -44,6 +44,6 @@ SPEC CHECKSUMS: "UITextField+Shake": 298ac5a0f239d731bdab999b19b628c956ca0ac3 XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: 1ac960a2c981ef98f7c24a3bba57bdabc1f66103 +PODFILE CHECKSUM: 27a1c2d82bffc5e7fcf004f2dfe9a6cdd15618d1 COCOAPODS: 1.11.3 From b9b4b5a853ea65b2c03c9fa6a490258af613d76e Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 6 Jun 2022 12:54:19 +0200 Subject: [PATCH 002/733] Ignore ruby files. --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6f4802cab..4e546bfcd 100644 --- a/.gitignore +++ b/.gitignore @@ -122,4 +122,9 @@ xcuserdata # Localization/StringsConvertor/input Localization/StringsConvertor/output -.DS_Store \ No newline at end of file +.DS_Store + + +## Ruby ### +vendor/ +.bundle/ From 1b97feba622609c6026ff5857d3b61007d03d06a Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 6 Jun 2022 13:18:30 +0200 Subject: [PATCH 003/733] Warning fixes --- .../HashtagTimelineViewModel+State.swift | 2 +- .../SearchDetailViewController.swift | 2 +- ...wViewControllerAnimatedTransitioning.swift | 33 ++++++++++--------- .../Sources/MastodonExtension/UIImage.swift | 2 +- .../Content/NotificationView+ViewModel.swift | 14 +++----- .../View/Content/StatusView+ViewModel.swift | 2 +- MastodonTests/MastodonTests.swift | 4 ++- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift index 6b75d3875..c74bde8cf 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift @@ -69,7 +69,7 @@ extension HashtagTimelineViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + guard viewModel != nil, let stateMachine = stateMachine else { return } stateMachine.enter(Loading.self) } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index ecc1c0c02..40d171c22 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -59,7 +59,7 @@ final class SearchDetailViewController: PageboyViewController, NeedsDependency { let searchController: CustomSearchController = { let searchController = CustomSearchController() searchController.automaticallyShowsScopeBar = false - searchController.dimsBackgroundDuringPresentation = false + searchController.obscuresBackgroundDuringPresentation = false return searchController }() private(set) lazy var searchBar: UISearchBar = { diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index 1b2d62211..4d5691336 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -241,23 +241,24 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { return rect }() let maskLayerToPath = maskLayerToRect.flatMap { UIBezierPath(rect: $0) }?.cgPath - let maskLayerToFinalRect: CGRect? = { - guard case .attachments = transitionItem.source else { return nil } - var rect = maskLayerToRect ?? transitionMaskView.frame - // clip tabBar when bar visible - guard let tabBarController = toVC.tabBarController, - !tabBarController.tabBar.isHidden, - let tabBarSuperView = tabBarController.tabBar.superview - else { return rect } - let tabBarFrameInWindow = tabBarSuperView.convert(tabBarController.tabBar.frame, to: nil) - let offset = rect.maxY - tabBarFrameInWindow.minY - guard offset > 0 else { return rect } - rect.size.height -= offset - return rect - }() - + + // FIXME: - let maskLayerToFinalPath = maskLayerToFinalRect.flatMap { UIBezierPath(rect: $0) }?.cgPath +// let maskLayerToFinalRect: CGRect? = { +// guard case .attachments = transitionItem.source else { return nil } +// var rect = maskLayerToRect ?? transitionMaskView.frame +// // clip tabBar when bar visible +// guard let tabBarController = toVC.tabBarController, +// !tabBarController.tabBar.isHidden, +// let tabBarSuperView = tabBarController.tabBar.superview +// else { return rect } +// let tabBarFrameInWindow = tabBarSuperView.convert(tabBarController.tabBar.frame, to: nil) +// let offset = rect.maxY - tabBarFrameInWindow.minY +// guard offset > 0 else { return rect } +// rect.size.height -= offset +// return rect +// }() +// let maskLayerToFinalPath = maskLayerToFinalRect.flatMap { UIBezierPath(rect: $0) }?.cgPath if let maskLayerToPath = maskLayerToPath { maskLayer.path = maskLayerToPath diff --git a/MastodonSDK/Sources/MastodonExtension/UIImage.swift b/MastodonSDK/Sources/MastodonExtension/UIImage.swift index e3560af63..bb50a1428 100644 --- a/MastodonSDK/Sources/MastodonExtension/UIImage.swift +++ b/MastodonSDK/Sources/MastodonExtension/UIImage.swift @@ -48,7 +48,7 @@ extension UIImage { guard let outputImage = filter.outputImage else { return nil } var bitmap = [UInt8](repeating: 0, count: 4) - let context = CIContext(options: [.workingColorSpace: kCFNull]) + let context = CIContext(options: [.workingColorSpace: kCFNull as Any]) context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil) return UIColor(red: CGFloat(bitmap[0]) / 255, green: CGFloat(bitmap[1]) / 255, blue: CGFloat(bitmap[2]) / 255, alpha: CGFloat(bitmap[3]) / 255) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index eec57cb5a..8367f30ec 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -97,15 +97,11 @@ extension NotificationView.ViewModel { $timestamp, timestampUpdatePublisher.prepend(Date()).eraseToAnyPublisher() ) - .sink { [weak self] timestamp, _ in - guard let self = self else { return } - guard let timestamp = timestamp else { - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: "")) - return - } - - let text = timestamp.localizedTimeAgoSinceNow - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: text)) + .map { timestamp, _ in + PlaintextMetaContent(string: timestamp?.localizedTimeAgoSinceNow ?? "") + } + .sink { text in + notificationView.dateLabel.configure(content: text) } .store(in: &disposeBag) // notification type indicator diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index f3d9f6f80..0834e29c8 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -451,7 +451,7 @@ extension StatusView.ViewModel { pollCountdownDescription ) .sink { pollVoteDescription, pollCountdownDescription in - statusView.pollVoteCountLabel.text = pollVoteDescription ?? "-" + statusView.pollVoteCountLabel.text = pollVoteDescription statusView.pollCountdownLabel.text = pollCountdownDescription ?? "-" } .store(in: &disposeBag) diff --git a/MastodonTests/MastodonTests.swift b/MastodonTests/MastodonTests.swift index 7264dde64..44e2cd95a 100644 --- a/MastodonTests/MastodonTests.swift +++ b/MastodonTests/MastodonTests.swift @@ -42,7 +42,9 @@ extension MastodonTests { } receiveValue: { domain in expectation.fulfill() } - wait(for: [expectation], timeout: 10) + withExtendedLifetime(cancellable) { + wait(for: [expectation], timeout: 10) + } } @available(iOS 15.0, *) From b3bc6dc273995d3e57d96c4c4624447a3099b907 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 15:50:36 -0500 Subject: [PATCH 004/733] Add accessibility labels to notifications, only have 1 element per notification --- .../Content/NotificationView+ViewModel.swift | 46 +++++++++++++------ .../View/Content/NotificationView.swift | 9 ++++ .../View/Content/StatusView+ViewModel.swift | 14 +++--- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index d7ba51e17..524c92146 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -54,7 +54,7 @@ extension NotificationView.ViewModel { bindAuthor(notificationView: notificationView) bindAuthorMenu(notificationView: notificationView) bindFollowRequest(notificationView: notificationView) - + $authContext .assign(to: \.authContext, on: notificationView.statusView.viewModel) .store(in: &disposeBag) @@ -100,21 +100,20 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) // timestamp - Publishers.CombineLatest( + let formattedTimestamp = Publishers.CombineLatest( $timestamp, timestampUpdatePublisher.prepend(Date()).eraseToAnyPublisher() ) - .sink { [weak self] timestamp, _ in - guard let self = self else { return } - guard let timestamp = timestamp else { - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: "")) - return - } - - let text = timestamp.localizedTimeAgoSinceNow - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: text)) + .map { timestamp, _ in + timestamp?.localizedTimeAgoSinceNow ?? "" } - .store(in: &disposeBag) + + formattedTimestamp + .sink { timestamp in + notificationView.dateLabel.configure(content: PlaintextMetaContent(string: timestamp)) + } + .store(in: &disposeBag) + // notification type indicator $notificationIndicatorText .sink { text in @@ -125,6 +124,27 @@ extension NotificationView.ViewModel { } } .store(in: &disposeBag) + + Publishers.CombineLatest4( + $authorName, + $authorUsername, + $notificationIndicatorText, + formattedTimestamp + ) + .sink { name, username, type, timestamp in + notificationView.accessibilityLabel = [ + "\(name?.string ?? "") \(type?.string ?? "")", + username.map { "@\($0)" } ?? "", + timestamp + ].joined(separator: ", ") + if !notificationView.statusView.isHidden { + notificationView.accessibilityLabel! += ", " + (notificationView.statusView.accessibilityLabel ?? "") + } + if !notificationView.quoteStatusViewContainerView.isHidden { + notificationView.accessibilityLabel! += ", " + (notificationView.quoteStatusView.accessibilityLabel ?? "") + } + } + .store(in: &disposeBag) } private func bindAuthorMenu(notificationView: NotificationView) { @@ -207,5 +227,5 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) } - + } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index e52422770..f6821dec7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -382,6 +382,15 @@ extension NotificationView { statusView.delegate = self quoteStatusView.delegate = self + + isAccessibilityElement = true + } +} + +extension NotificationView { + public override var accessibilityElements: [Any]? { + get { [] } + set {} } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 416226cbb..530294ea7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -709,13 +709,13 @@ extension StatusView.ViewModel { meidaAccessibilityLabel ) .map { author, content, media in - let group = [ - author, - content, - media - ] - - return group + var labels: [String?] = [content, media] + + if statusView.style != .notification { + labels.insert(author, at: 0) + } + + return labels .compactMap { $0 } .joined(separator: ", ") } From 393e4632da334fa2fc79686ffb7d3acf929fdcf5 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 16:33:54 -0500 Subject: [PATCH 005/733] Add secondary actions to notifications --- .../NotificationView+Configuration.swift | 1 + .../Transient/MastodonNotificationType.swift | 2 +- .../Content/NotificationView+ViewModel.swift | 56 ++++++++++++++++++- .../View/Content/NotificationView.swift | 31 ++++++++-- 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift index 98d06fd92..daa37a93b 100644 --- a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift +++ b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift @@ -111,6 +111,7 @@ extension NotificationView { self.viewModel.notificationIndicatorText = nil return } + self.viewModel.type = type func createMetaContent(text: String, emojis: MastodonContent.Emojis) -> MetaContent { let content = MastodonContent(content: text, emojis: emojis) diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonNotificationType.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonNotificationType.swift index 9e3029f26..455230d5e 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonNotificationType.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonNotificationType.swift @@ -7,7 +7,7 @@ import Foundation -public enum MastodonNotificationType: RawRepresentable { +public enum MastodonNotificationType: RawRepresentable, Equatable { case follow case followRequest case mention diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index 524c92146..b80486e14 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -25,7 +25,8 @@ extension NotificationView { let logger = Logger(subsystem: "NotificationView", category: "ViewModel") @Published public var authContext: AuthContext? - + + @Published public var type: MastodonNotificationType? @Published public var notificationIndicatorText: MetaContent? @Published public var authorAvatarImage: UIImage? @@ -145,6 +146,55 @@ extension NotificationView.ViewModel { } } .store(in: &disposeBag) + + Publishers.CombineLatest( + $authorAvatarImage, + $type + ) + .sink { avatarImage, type in + var actions = [UIAccessibilityCustomAction]() + + // these notifications can be directly actioned to view the profile + if type != .follow, type != .followRequest { + actions.append( + UIAccessibilityCustomAction( + name: L10n.Common.Controls.Status.showUserProfile, + image: avatarImage + ) { [weak notificationView] _ in + guard let notificationView = notificationView, let delegate = notificationView.delegate else { return false } + delegate.notificationView(notificationView, authorAvatarButtonDidPressed: notificationView.avatarButton) + return true + } + ) + } + + if type == .followRequest { + actions.append( + UIAccessibilityCustomAction( + name: L10n.Common.Controls.Actions.confirm, + image: Asset.Editing.checkmark20.image + ) { [weak notificationView] _ in + guard let notificationView = notificationView, let delegate = notificationView.delegate else { return false } + delegate.notificationView(notificationView, acceptFollowRequestButtonDidPressed: notificationView.acceptFollowRequestButton) + return true + } + ) + + actions.append( + UIAccessibilityCustomAction( + name: L10n.Common.Controls.Actions.delete, + image: Asset.Circles.forbidden20.image + ) { [weak notificationView] _ in + guard let notificationView = notificationView, let delegate = notificationView.delegate else { return false } + delegate.notificationView(notificationView, rejectFollowRequestButtonDidPressed: notificationView.rejectFollowRequestButton) + return true + } + ) + } + + notificationView.notificationActions = actions + } + .store(in: &disposeBag) } private func bindAuthorMenu(notificationView: NotificationView) { @@ -167,7 +217,9 @@ extension NotificationView.ViewModel { isMyself: isMyself, isBookmarking: false // no bookmark action display for notification item ) - notificationView.menuButton.menu = notificationView.setupAuthorMenu(menuContext: menuContext) + let (menu, actions) = notificationView.setupAuthorMenu(menuContext: menuContext) + notificationView.menuButton.menu = menu + notificationView.authorActions = actions notificationView.menuButton.showsMenuAsPrimaryAction = true notificationView.menuButton.isHidden = menuContext.isMyself diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index f6821dec7..d4828875b 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -46,7 +46,10 @@ public final class NotificationView: UIView { var _disposeBag = Set() public var disposeBag = Set() - + + var notificationActions = [UIAccessibilityCustomAction]() + var authorActions = [UIAccessibilityCustomAction]() + public private(set) lazy var viewModel: ViewModel = { let viewModel = ViewModel() viewModel.bind(notificationView: self) @@ -392,6 +395,21 @@ extension NotificationView { get { [] } set {} } + + public override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { + get { + var actions = notificationActions + actions += authorActions + if !statusView.isHidden { + actions += statusView.accessibilityCustomActions ?? [] + } + if !quoteStatusViewContainerView.isHidden { + actions += quoteStatusView.accessibilityCustomActions ?? [] + } + return actions + } + set {} + } } extension NotificationView { @@ -449,7 +467,7 @@ extension NotificationView: AdaptiveContainerView { extension NotificationView { public typealias AuthorMenuContext = StatusAuthorView.AuthorMenuContext - public func setupAuthorMenu(menuContext: AuthorMenuContext) -> UIMenu { + public func setupAuthorMenu(menuContext: AuthorMenuContext) -> (UIMenu, [UIAccessibilityCustomAction]) { var actions: [MastodonMenu.Action] = [] actions = [ @@ -475,8 +493,13 @@ extension NotificationView { actions: actions, delegate: self ) - - return menu + + let accessibilityActions = MastodonMenu.setupAccessibilityActions( + actions: actions, + delegate: self + ) + + return (menu, accessibilityActions) } } From c2232a596d207be0cf1be1a7091bedd1e1a51618 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 16:59:02 -0500 Subject: [PATCH 006/733] Improve accessibility labels for reply/reblog posts --- .../StatusThreadRootTableViewCell.swift | 1 - .../View/Content/StatusView+ViewModel.swift | 68 +++++++++++++------ .../MastodonUI/View/Content/StatusView.swift | 1 + 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift index 64f3456b5..350bf8660 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift @@ -96,7 +96,6 @@ extension StatusThreadRootTableViewCell { override var accessibilityElements: [Any]? { get { var elements = [ - statusView.headerContainerView, statusView.authorView, statusView.viewModel.isContentReveal ? statusView.contentMetaText.textView diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 530294ea7..66994f2a9 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -238,12 +238,11 @@ extension StatusView.ViewModel { } .store(in: &disposeBag) // username - let usernamePublisher = $authorUsername + $authorUsername .map { text -> String in guard let text = text else { return "" } return "@\(text)" } - usernamePublisher .sink { username in let metaContent = PlaintextMetaContent(string: username) authorView.authorUsernameLabel.configure(content: metaContent) @@ -270,18 +269,6 @@ extension StatusView.ViewModel { authorView.dateLabel.configure(content: PlaintextMetaContent(string: text)) } .store(in: &disposeBag) - - // accessibility label - Publishers.CombineLatest4($authorName, usernamePublisher, $timestampText, $timestamp) - .map { name, username, timestampText, timestamp in - let formatter = DateFormatter() - formatter.dateStyle = .medium - formatter.timeStyle = .short - let longTimestamp = timestamp.map { formatter.string(from: $0) } ?? "" - return "\(name?.string ?? "") \(username), \(timestampText). \(longTimestamp)" - } - .assign(to: \.accessibilityLabel, on: authorView) - .store(in: &disposeBag) } private func bindContent(statusView: StatusView) { @@ -634,7 +621,7 @@ extension StatusView.ViewModel { } private func bindAccessibility(statusView: StatusView) { - let authorAccessibilityLabel = Publishers.CombineLatest3( + let shortAuthorAccessibilityLabel = Publishers.CombineLatest3( $header, $authorName, $timestampText @@ -644,19 +631,56 @@ extension StatusView.ViewModel { switch header { case .none: - break + strings.append(authorName?.string) case .reply(let info): + strings.append(authorName?.string) strings.append(info.header.string) case .repost(let info): strings.append(info.header.string) + strings.append(authorName?.string) } - strings.append(authorName?.string) strings.append(timestamp) return strings.compactMap { $0 }.joined(separator: ", ") } - + + let longTimestampFormatter = DateFormatter() + longTimestampFormatter.dateStyle = .medium + longTimestampFormatter.timeStyle = .short + let longTimestampLabel = Publishers.CombineLatest( + $timestampText, + $timestamp.map { timestamp in + if let timestamp { + return longTimestampFormatter.string(from: timestamp) + } + return "" + } + ) + .map { timestampText, longTimestamp in + "\(timestampText). \(longTimestamp)" + } + + Publishers.CombineLatest4( + $header, + $authorName, + $authorUsername, + longTimestampLabel + ) + .map { header, name, username, timestamp in + let nameAndUsername = "\(name?.string ?? "") @\(username ?? "")" + switch header { + case .none: + return "\(nameAndUsername), \(timestamp)" + case .repost(info: let info): + return "\(info.header.string) \(nameAndUsername), \(timestamp)" + case .reply(info: let info): + return "\(nameAndUsername) \(info.header.string), \(timestamp)" + } + } + .assign(to: \.accessibilityLabel, on: statusView.authorView) + .store(in: &disposeBag) + let contentAccessibilityLabel = Publishers.CombineLatest3( $isContentReveal, $spoilerContent, @@ -694,8 +718,8 @@ extension StatusView.ViewModel { statusView.spoilerOverlayView.accessibilityLabel = contentAccessibilityLabel } .store(in: &disposeBag) - - let meidaAccessibilityLabel = $mediaViewConfigurations + + let mediaAccessibilityLabel = $mediaViewConfigurations .map { configurations -> String? in let count = configurations.count return L10n.Plural.Count.media(count) @@ -704,9 +728,9 @@ extension StatusView.ViewModel { // TODO: Toolbar Publishers.CombineLatest3( - authorAccessibilityLabel, + shortAuthorAccessibilityLabel, contentAccessibilityLabel, - meidaAccessibilityLabel + mediaAccessibilityLabel ) .map { author, content, media in var labels: [String?] = [content, media] diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 563bc7e3d..21410b9e2 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -246,6 +246,7 @@ extension StatusView { // header headerIconImageView.isUserInteractionEnabled = false headerInfoLabel.isUserInteractionEnabled = false + headerInfoLabel.isAccessibilityElement = false let headerTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer headerTapGestureRecognizer.addTarget(self, action: #selector(StatusView.headerDidPressed(_:))) headerContainerView.addGestureRecognizer(headerTapGestureRecognizer) From ed9911ca76b7d4e51901fbb5b47b76cea0f2732a Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 17:30:57 -0500 Subject: [PATCH 007/733] =?UTF-8?q?Rename=20tab=20to=20=E2=80=9CNotificati?= =?UTF-8?q?ons=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StringsConvertor/input/en.lproj/app.json | 2 +- Localization/app.json | 2 +- Mastodon/Coordinator/SceneCoordinator.swift | 4 ++-- .../Root/MainTab/MainTabBarController.swift | 18 +++++++++--------- .../Scene/Root/Sidebar/SidebarViewModel.swift | 6 +++--- Mastodon/Supporting Files/SceneDelegate.swift | 2 +- .../Generated/Strings.swift | 4 ++-- .../Resources/en.lproj/Localizable.strings | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 8867385e2..ff2926996 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { diff --git a/Localization/app.json b/Localization/app.json index 8867385e2..ff2926996 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 8a0825969..737d74d7e 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -71,8 +71,8 @@ final public class SceneCoordinator { self.setup() try await Task.sleep(nanoseconds: .second * 1) - // redirect to notification tab - self.switchToTabBar(tab: .notification) + // redirect to notifications tab + self.switchToTabBar(tab: .notifications) // Delay in next run loop DispatchQueue.main.async { [weak self] in diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index c49dcc1a1..4f6b21d96 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -49,7 +49,7 @@ class MainTabBarController: UITabBarController { case home case search case compose - case notification + case notifications case me var tag: Int { @@ -61,7 +61,7 @@ class MainTabBarController: UITabBarController { case .home: return L10n.Common.Controls.Tabs.home case .search: return L10n.Common.Controls.Tabs.search case .compose: return L10n.Common.Controls.Actions.compose - case .notification: return L10n.Common.Controls.Tabs.notification + case .notifications: return L10n.Common.Controls.Tabs.notifications case .me: return L10n.Common.Controls.Tabs.profile } } @@ -71,7 +71,7 @@ class MainTabBarController: UITabBarController { case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate) case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate) case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) - case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + case .notifications: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) case .me: return UIImage(systemName: "person")! } } @@ -81,7 +81,7 @@ class MainTabBarController: UITabBarController { case .home: return Asset.ObjectsAndTools.houseFill.image.withRenderingMode(.alwaysTemplate) case .search: return Asset.ObjectsAndTools.magnifyingglassFill.image.withRenderingMode(.alwaysTemplate) case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) - case .notification: return Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) + case .notifications: return Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) case .me: return UIImage(systemName: "person.fill")! } } @@ -91,7 +91,7 @@ class MainTabBarController: UITabBarController { case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) - case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) + case .notifications: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) case .me: return UIImage(systemName: "person", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! } } @@ -101,7 +101,7 @@ class MainTabBarController: UITabBarController { case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate) case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate) case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) - case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + case .notifications: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) case .me: return UIImage(systemName: "person")! } } @@ -127,7 +127,7 @@ class MainTabBarController: UITabBarController { viewController = _viewController case .compose: viewController = UIViewController() - case .notification: + case .notifications: let _viewController = NotificationViewController() _viewController.context = context _viewController.coordinator = coordinator @@ -272,7 +272,7 @@ extension MainTabBarController { } ?? false let image: UIImage = { - if currentTab == .notification { + if currentTab == .notifications { return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadgeFill.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) } else { return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadge.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) @@ -593,7 +593,7 @@ extension MainTabBarController { let tabs: [Tab] = [ .home, .search, - .notification, + .notifications, .me ] for (i, tab) in tabs.enumerated() { diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift index c3f9e3e36..7c323bbca 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift @@ -100,7 +100,7 @@ extension SidebarViewModel { .store(in: &cell.disposeBag) switch item { - case .notification: + case .notifications: Publishers.CombineLatest( self.context.notificationService.unreadNotificationCountDidUpdate, self.$currentTab @@ -116,7 +116,7 @@ extension SidebarViewModel { }() let image: UIImage = { - if currentTab == .notification { + if currentTab == .notifications { return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadgeFill.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) } else { return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadge.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) @@ -192,7 +192,7 @@ extension SidebarViewModel { let items: [Item] = [ .tab(.home), .tab(.search), - .tab(.notification), + .tab(.notifications), .tab(.me), .setting, ] diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 1e97fb179..b25f7c5eb 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -172,7 +172,7 @@ extension SceneDelegate { return false } - coordinator.switchToTabBar(tab: .notification) + coordinator.switchToTabBar(tab: .notifications) case "org.joinmastodon.app.new-post": if coordinator?.tabBarController.topMost is ComposeViewController { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 44ae29267..684ba439f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -366,8 +366,8 @@ public enum L10n { public enum Tabs { /// Home public static let home = L10n.tr("Localizable", "Common.Controls.Tabs.Home") - /// Notification - public static let notification = L10n.tr("Localizable", "Common.Controls.Tabs.Notification") + /// Notifications + public static let notifications = L10n.tr("Localizable", "Common.Controls.Tabs.Notifications") /// Profile public static let profile = L10n.tr("Localizable", "Common.Controls.Tabs.Profile") /// Search diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 9114b96e5..ac09ab1f4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -131,7 +131,7 @@ Please check your internet connection."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; "Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Home"; -"Common.Controls.Tabs.Notification" = "Notification"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profile"; "Common.Controls.Tabs.Search" = "Search"; "Common.Controls.Timeline.Filtered" = "Filtered"; From daeb2ef70ffa8d7756e60cff45259dbc32b56da4 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Fri, 11 Nov 2022 18:35:18 -0800 Subject: [PATCH 008/733] wip --- .../xcshareddata/swiftpm/Package.resolved | 9 ++ MastodonSDK/Package.swift | 2 + .../View/Content/OpenGraphView.swift | 82 +++++++++++++++++++ .../View/Content/StatusView+ViewModel.swift | 16 ++++ .../MastodonUI/View/Content/StatusView.swift | 11 ++- 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 64dc691bb..35c4b5ffc 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -108,6 +108,15 @@ "version" : "8.0.0" } }, + { + "identity" : "opengraph", + "kind" : "remoteSourceControl", + "location" : "https://github.com/satoshi-takano/OpenGraph", + "state" : { + "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", + "version" : "1.5.0" + } + }, { "identity" : "pageboy", "kind" : "remoteSourceControl", diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index ca241038b..d44e0d122 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -49,6 +49,7 @@ let package = Package( .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.12.0"), .package(url: "https://github.com/eneko/Stripes.git", from: "0.2.0"), .package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.4.1"), + .package(url: "https://github.com/satoshi-takano/OpenGraph", from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -117,6 +118,7 @@ let package = Package( .product(name: "UIHostingConfigurationBackport", package: "UIHostingConfigurationBackport"), .product(name: "TabBarPager", package: "TabBarPager"), .product(name: "ThirdPartyMailer", package: "ThirdPartyMailer"), + .product(name: "OpenGraph", package: "OpenGraph"), .product(name: "OrderedCollections", package: "swift-collections"), .product(name: "Tabman", package: "Tabman"), .product(name: "MetaTextKit", package: "MetaTextKit"), diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift new file mode 100644 index 000000000..f03fda847 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift @@ -0,0 +1,82 @@ +// +// OpenGraphView.swift +// +// +// Created by Kyle Bashour on 11/11/22. +// + +import MastodonAsset +import MastodonCore +import OpenGraph +import UIKit + +public final class OpenGraphView: UIControl { + private let containerStackView = UIStackView() + private let labelStackView = UIStackView() + + private let imageView = UIImageView() + private let titleLabel = UILabel() + private let subtitleLabel = UILabel() + + public override init(frame: CGRect) { + super.init(frame: frame) + + clipsToBounds = true + layer.cornerCurve = .continuous + layer.cornerRadius = 10 + layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor + backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor + + titleLabel.numberOfLines = 0 + titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) + titleLabel.text = "This is where I'd put a title... if I had one" + titleLabel.textColor = Asset.Colors.Label.primary.color + + subtitleLabel.text = "Subtitle" + subtitleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) + subtitleLabel.textColor = Asset.Colors.Label.secondary.color + subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20) + + imageView.backgroundColor = UIColor.black.withAlphaComponent(0.15) + + labelStackView.addArrangedSubview(titleLabel) + labelStackView.addArrangedSubview(subtitleLabel) + labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10) + labelStackView.isLayoutMarginsRelativeArrangement = true + labelStackView.axis = .vertical + + containerStackView.addArrangedSubview(imageView) + containerStackView.addArrangedSubview(labelStackView) + containerStackView.distribution = .fill + containerStackView.alignment = .center + + addSubview(containerStackView) + + containerStackView.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + containerStackView.heightAnchor.constraint(equalToConstant: 80), + containerStackView.topAnchor.constraint(equalTo: topAnchor), + containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor), + containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor), + containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor), + imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func configure(content: String) { + self.subtitleLabel.text = content + } + + public override func didMoveToWindow() { + super.didMoveToWindow() + + if let window = window { + layer.borderWidth = 1 / window.screen.scale + } + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 416226cbb..c17f41074 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -317,6 +317,22 @@ extension StatusView.ViewModel { ) statusView.contentMetaText.textView.accessibilityTraits = [.staticText] statusView.contentMetaText.textView.accessibilityElementsHidden = false + + if let url = content.entities.first(where: { + switch $0.meta { + case .url: + return true + default: + return false + } + }) { + guard case .url(let text, let trimmed, let url, _) = url.meta, let url = URL(string: url) else { + fatalError() + } + + statusView.linkPreview.configure(content: trimmed) + statusView.setLinkPreviewDisplay() + } } else { statusView.contentMetaText.reset() statusView.contentMetaText.textView.accessibilityLabel = "" diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 563bc7e3d..a3d953f0a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -113,6 +113,8 @@ public final class StatusView: UIView { ] return metaText }() + + public let linkPreview = OpenGraphView() // content warning public let spoilerOverlayView = SpoilerOverlayView() @@ -217,6 +219,7 @@ public final class StatusView: UIView { setMediaDisplay(isDisplay: false) setPollDisplay(isDisplay: false) setFilterHintLabelDisplay(isDisplay: false) + setLinkPreviewDisplay(isDisplay: false) } public override init(frame: CGRect) { @@ -378,7 +381,7 @@ extension StatusView.Style { statusView.contentContainer.axis = .vertical statusView.contentContainer.spacing = 12 statusView.contentContainer.distribution = .fill - statusView.contentContainer.alignment = .top + statusView.contentContainer.alignment = .fill statusView.contentAdaptiveMarginContainerView.contentView = statusView.contentContainer statusView.contentAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin @@ -389,6 +392,8 @@ extension StatusView.Style { // status content statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView) statusView.containerStackView.setCustomSpacing(16, after: statusView.contentMetaText.textView) + statusView.contentContainer.addArrangedSubview(statusView.linkPreview) + statusView.containerStackView.setCustomSpacing(16, after: statusView.linkPreview) statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false statusView.containerStackView.addSubview(statusView.spoilerOverlayView) @@ -539,6 +544,10 @@ extension StatusView { func setFilterHintLabelDisplay(isDisplay: Bool = true) { filterHintLabel.isHidden = !isDisplay } + + func setLinkPreviewDisplay(isDisplay: Bool = true) { + linkPreview.isHidden = !isDisplay + } // container width public var contentMaxLayoutWidth: CGFloat { From daedd2b5be132c7d035f27d598908ac9c421270d Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sat, 12 Nov 2022 13:41:01 -0800 Subject: [PATCH 009/733] [Welcome] Allow buttons to grow with Dynamic Type. The buttons now have a minimum height rather than a constant height. Also made a couple minor improvements / bug fixes: - Both buttons now react to Dynamic Type settings changes (enabled `adjustsFontForContentSizeCategory`). - A layout pass is now enforced in traitCollectionDidChange to ensure that setupButtonShadowView is using the right bounds. - signUpButtonShadowView now uses signUpButtonShadowView's bounds. --- .../Onboarding/Welcome/WelcomeViewController.swift | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index a2b8df83a..225f2f9ef 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -51,6 +51,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signUpButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false + button.titleLabel?.adjustsFontForContentSizeCategory = true button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) button.setTitle(L10n.Common.Controls.Actions.signUp, for: .normal) let backgroundImageColor: UIColor = .white @@ -65,6 +66,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signInButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false + button.titleLabel?.adjustsFontForContentSizeCategory = true button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) button.setTitle(L10n.Scene.Welcome.logIn, for: .normal) let backgroundImageColor = Asset.Scene.Welcome.signInButtonBackground.color @@ -113,12 +115,12 @@ extension WelcomeViewController { signUpButton.translatesAutoresizingMaskIntoConstraints = false buttonContainer.addArrangedSubview(signUpButton) NSLayoutConstraint.activate([ - signUpButton.heightAnchor.constraint(equalToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1), + signUpButton.heightAnchor.constraint(greaterThanOrEqualToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1), ]) signInButton.translatesAutoresizingMaskIntoConstraints = false buttonContainer.addArrangedSubview(signInButton) NSLayoutConstraint.activate([ - signInButton.heightAnchor.constraint(equalToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1), + signInButton.heightAnchor.constraint(greaterThanOrEqualToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1), ]) signUpButtonShadowView.translatesAutoresizingMaskIntoConstraints = false @@ -172,7 +174,9 @@ extension WelcomeViewController { override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) - + + view.layoutIfNeeded() + setupIllustrationLayout() setupButtonShadowView() } @@ -189,7 +193,7 @@ extension WelcomeViewController { y: 1, blur: 2, spread: 0, - roundedRect: signInButtonShadowView.bounds, + roundedRect: signUpButtonShadowView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 10, height: 10) ) From 87df13987a6970f6b7d4a29e5445082141e25e79 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sat, 12 Nov 2022 20:30:57 -0800 Subject: [PATCH 010/733] Ensure that the welcome buttons have adequate padding at larger Dynamic Type configurations. --- .../Onboarding/Share/OnboardingViewControllerAppearance.swift | 4 ++++ Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift index ba1eecfc5..ee01b99e8 100644 --- a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift +++ b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift @@ -22,6 +22,10 @@ extension OnboardingViewControllerAppearance { static var actionButtonMarginExtend: CGFloat { return 80 } static var viewBottomPaddingHeight: CGFloat { return 11 } static var viewBottomPaddingHeightExtend: CGFloat { return 22 } + + // Typically assigned to the button's contentEdgeInsets. Ensures space around content, even when + // content is large due to Dynamic Type. + static var actionButtonPadding: UIEdgeInsets { return UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) } static var largeTitleFont: UIFont { return UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold)) diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 225f2f9ef..a7703bfaa 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -51,6 +51,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signUpButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false + button.contentEdgeInsets = WelcomeViewController.actionButtonPadding button.titleLabel?.adjustsFontForContentSizeCategory = true button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) button.setTitle(L10n.Common.Controls.Actions.signUp, for: .normal) @@ -66,6 +67,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signInButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false + button.contentEdgeInsets = WelcomeViewController.actionButtonPadding button.titleLabel?.adjustsFontForContentSizeCategory = true button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) button.setTitle(L10n.Scene.Welcome.logIn, for: .normal) From 0f495e17dd25747a4f3b7967e2ddf30ae3790577 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sat, 12 Nov 2022 20:22:57 -0800 Subject: [PATCH 011/733] Adjust the padding and layout of the NavigationActionView. --- .../Share/NavigationActionView.swift | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Onboarding/Share/NavigationActionView.swift b/Mastodon/Scene/Onboarding/Share/NavigationActionView.swift index c3236bdb4..47a1afbfc 100644 --- a/Mastodon/Scene/Onboarding/Share/NavigationActionView.swift +++ b/Mastodon/Scene/Onboarding/Share/NavigationActionView.swift @@ -13,6 +13,7 @@ import MastodonLocalization final class NavigationActionView: UIView { static let buttonHeight: CGFloat = 50 + static let minimumBackButtonWidth: CGFloat = 100 private var observations = Set() @@ -27,6 +28,8 @@ final class NavigationActionView: UIView { let backButton: PrimaryActionButton = { let button = PrimaryActionButton() button.action = .back + button.contentEdgeInsets = WelcomeViewController.actionButtonPadding + button.titleLabel?.adjustsFontForContentSizeCategory = true button.setTitle(L10n.Common.Controls.Actions.back, for: .normal) return button }() @@ -35,6 +38,8 @@ final class NavigationActionView: UIView { let nextButton: PrimaryActionButton = { let button = PrimaryActionButton() button.action = .next + button.contentEdgeInsets = WelcomeViewController.actionButtonPadding + button.titleLabel?.adjustsFontForContentSizeCategory = true button.setTitle(L10n.Common.Controls.Actions.next, for: .normal) return button }() @@ -77,9 +82,8 @@ extension NavigationActionView { nextButtonShadowContainer.translatesAutoresizingMaskIntoConstraints = false buttonContainer.addArrangedSubview(nextButtonShadowContainer) NSLayoutConstraint.activate([ - backButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1), - nextButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1), - nextButtonShadowContainer.widthAnchor.constraint(equalTo: backButtonShadowContainer.widthAnchor, multiplier: 2).priority(.required - 1), + backButtonShadowContainer.heightAnchor.constraint(greaterThanOrEqualToConstant: NavigationActionView.buttonHeight).priority(.required - 1), + nextButtonShadowContainer.heightAnchor.constraint(greaterThanOrEqualToConstant: NavigationActionView.buttonHeight).priority(.required - 1), ]) backButton.translatesAutoresizingMaskIntoConstraints = false @@ -99,6 +103,17 @@ extension NavigationActionView { nextButton.trailingAnchor.constraint(equalTo: nextButtonShadowContainer.trailingAnchor), nextButton.bottomAnchor.constraint(equalTo: nextButtonShadowContainer.bottomAnchor), ]) + + // We want the back button to be as small as possible, allowing the next button to take up + // any remaining space. .defaultLow is "the priority level at which a button hugs its + // contents horizontally". Setting this on backButton allows nextButton to eat up remaining + // space. Note that we have to set this on the backButton, not the container, because it's + // backButton's size that determines the compression amount. + backButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + // Ensure that the back button has a reasonable minimum tap area. + NSLayoutConstraint.activate([ + backButton.widthAnchor.constraint(greaterThanOrEqualToConstant: NavigationActionView.minimumBackButtonWidth).priority(.defaultLow - 1) + ]) } } From a36a303532e35b024d5990f3725a84700726e6c9 Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 14 Nov 2022 02:53:59 +0900 Subject: [PATCH 012/733] Fix typos --- Mastodon/Scene/Account/AccountListViewModel.swift | 4 ++-- Mastodon/Scene/Profile/ProfileViewController.swift | 2 +- .../Sources/CoreDataStack/Utility/ManagedObjectRecord.swift | 2 +- .../Sources/MastodonCore/Service/AuthenticationService.swift | 4 ++-- .../Scene/ComposeContent/ComposeContentViewModel.swift | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Mastodon/Scene/Account/AccountListViewModel.swift b/Mastodon/Scene/Account/AccountListViewModel.swift index e0aaf97fc..c5bd93f07 100644 --- a/Mastodon/Scene/Account/AccountListViewModel.swift +++ b/Mastodon/Scene/Account/AccountListViewModel.swift @@ -52,7 +52,7 @@ final class AccountListViewModel: NSObject { mastodonAuthenticationFetchedResultsController.delegate = self do { try mastodonAuthenticationFetchedResultsController.performFetch() - authentications = mastodonAuthenticationFetchedResultsController.fetchedObjects?.compactMap { $0.asRecrod } ?? [] + authentications = mastodonAuthenticationFetchedResultsController.fetchedObjects?.compactMap { $0.asRecord } ?? [] } catch { assertionFailure(error.localizedDescription) } @@ -183,7 +183,7 @@ extension AccountListViewModel: NSFetchedResultsControllerDelegate { return } - authentications = mastodonAuthenticationFetchedResultsController.fetchedObjects?.compactMap { $0.asRecrod } ?? [] + authentications = mastodonAuthenticationFetchedResultsController.fetchedObjects?.compactMap { $0.asRecord } ?? [] } } diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 3ce1fd33a..6c42f7643 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -540,7 +540,7 @@ extension ProfileViewController { let composeViewModel = ComposeViewModel( context: context, authContext: viewModel.authContext, - kind: .mention(user: mastodonUser.asRecrod) + kind: .mention(user: mastodonUser.asRecord) ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } diff --git a/MastodonSDK/Sources/CoreDataStack/Utility/ManagedObjectRecord.swift b/MastodonSDK/Sources/CoreDataStack/Utility/ManagedObjectRecord.swift index 4910145cf..88b08fc3c 100644 --- a/MastodonSDK/Sources/CoreDataStack/Utility/ManagedObjectRecord.swift +++ b/MastodonSDK/Sources/CoreDataStack/Utility/ManagedObjectRecord.swift @@ -32,7 +32,7 @@ public class ManagedObjectRecord: Hashable { } extension Managed where Self: NSManagedObject { - public var asRecrod: ManagedObjectRecord { + public var asRecord: ManagedObjectRecord { return .init(objectID: objectID) } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/AuthenticationService.swift b/MastodonSDK/Sources/MastodonCore/Service/AuthenticationService.swift index 48da254c6..e8cb536ac 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/AuthenticationService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/AuthenticationService.swift @@ -67,7 +67,7 @@ public final class AuthenticationService: NSObject { try mastodonAuthenticationFetchedResultsController.performFetch() mastodonAuthentications = mastodonAuthenticationFetchedResultsController.fetchedObjects? .sorted(by: { $0.activedAt > $1.activedAt }) - .compactMap { $0.asRecrod } ?? [] + .compactMap { $0.asRecord } ?? [] } catch { assertionFailure(error.localizedDescription) } @@ -148,7 +148,7 @@ extension AuthenticationService: NSFetchedResultsControllerDelegate { mastodonAuthentications = mastodonAuthenticationFetchedResultsController.fetchedObjects? .sorted(by: { $0.activedAt > $1.activedAt }) - .compactMap { $0.asRecrod } ?? [] + .compactMap { $0.asRecord } ?? [] } } diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index 2bf4e26ff..62159667f 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -472,7 +472,7 @@ extension ComposeContentViewModel { let managedObjectContext = self.context.managedObjectContext var _author: ManagedObjectRecord? managedObjectContext.performAndWait { - _author = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user.asRecrod + _author = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user.asRecord } guard let author = _author else { throw AppError.badAuthentication From 88b54b2962fd9ebef957332e6198bbad8b7edb7c Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 14 Nov 2022 02:56:20 +0900 Subject: [PATCH 013/733] Fix typos --- .../SearchResult/SearchResultViewModel+Diffable.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift index 7d243b1fa..b9eb5a9ae 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift @@ -33,7 +33,7 @@ extension SearchResultViewModel { userFetchedResultsController.$records, $hashtags ) - .map { statusRecrods, userRecords, hashtags in + .map { statusRecords, userRecords, hashtags in var items: [SearchResultItem] = [] let userItems = userRecords.map { SearchResultItem.user($0) } @@ -42,7 +42,7 @@ extension SearchResultViewModel { let hashtagItems = hashtags.map { SearchResultItem.hashtag(tag: $0) } items.append(contentsOf: hashtagItems) - let statusItems = statusRecrods.map { SearchResultItem.status($0) } + let statusItems = statusRecords.map { SearchResultItem.status($0) } items.append(contentsOf: statusItems) return items From ae24f95e313a9f1c40c7a4278755cee4dfd9f60e Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Mon, 14 Nov 2022 13:26:25 -0800 Subject: [PATCH 014/733] wip --- ...raphView.swift => LinkPreviewButton.swift} | 56 +++++++++++++++++-- .../View/Content/StatusView+ViewModel.swift | 4 +- .../MastodonUI/View/Content/StatusView.swift | 12 ++-- 3 files changed, 59 insertions(+), 13 deletions(-) rename MastodonSDK/Sources/MastodonUI/View/Content/{OpenGraphView.swift => LinkPreviewButton.swift} (64%) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift similarity index 64% rename from MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift rename to MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index f03fda847..344511217 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/OpenGraphView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -5,12 +5,17 @@ // Created by Kyle Bashour on 11/11/22. // +import AlamofireImage +import LinkPresentation import MastodonAsset import MastodonCore import OpenGraph import UIKit -public final class OpenGraphView: UIControl { +public final class LinkPreviewButton: UIControl { + private var linkPresentationTask: Task? + private var url: URL? + private let containerStackView = UIStackView() private let labelStackView = UIStackView() @@ -27,17 +32,20 @@ public final class OpenGraphView: UIControl { layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor - titleLabel.numberOfLines = 0 + titleLabel.numberOfLines = 2 titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) titleLabel.text = "This is where I'd put a title... if I had one" titleLabel.textColor = Asset.Colors.Label.primary.color subtitleLabel.text = "Subtitle" + subtitleLabel.numberOfLines = 1 subtitleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) subtitleLabel.textColor = Asset.Colors.Label.secondary.color subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20) imageView.backgroundColor = UIColor.black.withAlphaComponent(0.15) + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true labelStackView.addArrangedSubview(titleLabel) labelStackView.addArrangedSubview(subtitleLabel) @@ -55,12 +63,13 @@ public final class OpenGraphView: UIControl { containerStackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - containerStackView.heightAnchor.constraint(equalToConstant: 80), + containerStackView.heightAnchor.constraint(equalToConstant: 85), containerStackView.topAnchor.constraint(equalTo: topAnchor), containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor), containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor), containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor), imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), + imageView.heightAnchor.constraint(equalTo: heightAnchor), ]) } @@ -68,8 +77,37 @@ public final class OpenGraphView: UIControl { fatalError("init(coder:) has not been implemented") } - public func configure(content: String) { - self.subtitleLabel.text = content + public func configure(url: URL, trimmed: String) { + guard url != self.url else { + return + } + + reset() + subtitleLabel.text = trimmed + self.url = url + + linkPresentationTask = Task { + do { + let metadata = try await LPMetadataProvider().startFetchingMetadata(for: url) + + guard !Task.isCancelled else { + return + } + + self.titleLabel.text = metadata.title + if let result = try await metadata.imageProvider?.loadImageData() { + let image = UIImage(data: result.data) + + guard !Task.isCancelled else { + return + } + + self.imageView.image = image + } + } catch { + self.subtitleLabel.text = "Error loading link preview" + } + } } public override func didMoveToWindow() { @@ -79,4 +117,12 @@ public final class OpenGraphView: UIControl { layer.borderWidth = 1 / window.screen.scale } } + + private func reset() { + linkPresentationTask?.cancel() + url = nil + imageView.image = nil + titleLabel.text = nil + subtitleLabel.text = nil + } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index c17f41074..e18bfc953 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -330,8 +330,8 @@ extension StatusView.ViewModel { fatalError() } - statusView.linkPreview.configure(content: trimmed) - statusView.setLinkPreviewDisplay() + statusView.linkPreviewButton.configure(url: url, trimmed: trimmed) + statusView.setLinkPreviewButtonDisplay() } } else { statusView.contentMetaText.reset() diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index a3d953f0a..eab862411 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -114,7 +114,7 @@ public final class StatusView: UIView { return metaText }() - public let linkPreview = OpenGraphView() + public let linkPreviewButton = LinkPreviewButton() // content warning public let spoilerOverlayView = SpoilerOverlayView() @@ -219,7 +219,7 @@ public final class StatusView: UIView { setMediaDisplay(isDisplay: false) setPollDisplay(isDisplay: false) setFilterHintLabelDisplay(isDisplay: false) - setLinkPreviewDisplay(isDisplay: false) + setLinkPreviewButtonDisplay(isDisplay: false) } public override init(frame: CGRect) { @@ -392,8 +392,8 @@ extension StatusView.Style { // status content statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView) statusView.containerStackView.setCustomSpacing(16, after: statusView.contentMetaText.textView) - statusView.contentContainer.addArrangedSubview(statusView.linkPreview) - statusView.containerStackView.setCustomSpacing(16, after: statusView.linkPreview) + statusView.contentContainer.addArrangedSubview(statusView.linkPreviewButton) + statusView.containerStackView.setCustomSpacing(16, after: statusView.linkPreviewButton) statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false statusView.containerStackView.addSubview(statusView.spoilerOverlayView) @@ -545,8 +545,8 @@ extension StatusView { filterHintLabel.isHidden = !isDisplay } - func setLinkPreviewDisplay(isDisplay: Bool = true) { - linkPreview.isHidden = !isDisplay + func setLinkPreviewButtonDisplay(isDisplay: Bool = true) { + linkPreviewButton.isHidden = !isDisplay } // container width From 35f6732ad924b9d56ceb2f253d31d164890882a4 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 14 Nov 2022 20:10:05 -0500 Subject: [PATCH 015/733] update generated files --- .../StringsConvertor/input/Base.lproj/app.json | 4 ++++ .../MastodonLocalization/Generated/Strings.swift | 12 ++++++------ .../Resources/Base.lproj/Localizable.strings | 2 ++ .../Resources/en.lproj/Localizable.strings | 4 +--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index c40c0a39e..30566d8d6 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -448,6 +448,10 @@ "placeholder": { "label": "Label", "content": "Content" + }, + "verified": { + "short": "Verified on %s", + "long": "Ownership of this link was checked on %s" } }, "segmented_control": { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 65a97c615..1ad98b0ea 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -742,13 +742,13 @@ public enum L10n { public static let label = L10n.tr("Localizable", "Scene.Profile.Fields.Placeholder.Label", fallback: "Label") } public enum Verified { - /// Ownership of this link was checked on %s - public static func long(_ p1: UnsafePointer) -> String { - return L10n.tr("Localizable", "Scene.Profile.Fields.Verified.Long", p1) + /// Ownership of this link was checked on %@ + public static func long(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Profile.Fields.Verified.Long", String(describing: p1), fallback: "Ownership of this link was checked on %@") } - /// Verified at %s - public static func short(_ p1: UnsafePointer) -> String { - return L10n.tr("Localizable", "Scene.Profile.Fields.Verified.Short", p1) + /// Verified on %@ + public static func short(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Profile.Fields.Verified.Short", String(describing: p1), fallback: "Verified on %@") } } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index a352b0526..73bc292cf 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -267,6 +267,8 @@ uploaded to Mastodon."; "Scene.Profile.Fields.AddRow" = "Add Row"; "Scene.Profile.Fields.Placeholder.Content" = "Content"; "Scene.Profile.Fields.Placeholder.Label" = "Label"; +"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; +"Scene.Profile.Fields.Verified.Short" = "Verified on %@"; "Scene.Profile.Header.FollowsYou" = "Follows You"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index e269a45a7..07ccd2c1b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -263,8 +263,6 @@ uploaded to Mastodon."; "Scene.Profile.Fields.AddRow" = "Add Row"; "Scene.Profile.Fields.Placeholder.Content" = "Content"; "Scene.Profile.Fields.Placeholder.Label" = "Label"; -"Scene.Profile.Fields.Verified.Short" = "Verified at %s"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %s"; "Scene.Profile.Header.FollowsYou" = "Follows You"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account"; @@ -456,4 +454,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file From ac28c2ee4f4d24fcab5d0442f2ea0e4eed12e910 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 14 Nov 2022 20:44:47 -0500 Subject: [PATCH 016/733] Add Live Text support to MediaPreviewImageView --- .../Image/MediaPreviewImageView.swift | 45 +++++++++++++++++-- .../MediaPreviewImageViewController.swift | 42 ++++++++++++++++- .../MastodonExtension/ImageAnalyzer.swift | 13 ++++++ 3 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonExtension/ImageAnalyzer.swift diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift index 05f2ce70f..cc31a9639 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift @@ -9,6 +9,7 @@ import os.log import func AVFoundation.AVMakeRect import UIKit import FLAnimatedImage +import VisionKit final class MediaPreviewImageView: UIScrollView { @@ -28,9 +29,21 @@ final class MediaPreviewImageView: UIScrollView { tapGestureRecognizer.numberOfTapsRequired = 2 return tapGestureRecognizer }() - + private var containerFrame: CGRect? - + + private var _interaction: UIInteraction? = { + if #available(iOS 16.0, *) { + return ImageAnalysisInteraction() + } else { + return nil + } + }() + @available(iOS 16.0, *) + var liveTextInteraction: ImageAnalysisInteraction { + _interaction as! ImageAnalysisInteraction + } + override init(frame: CGRect) { super.init(frame: frame) _init() @@ -55,10 +68,14 @@ extension MediaPreviewImageView { maximumZoomScale = 4.0 addSubview(imageView) - + doubleTapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageView.doubleTapGestureRecognizerHandler(_:))) imageView.addGestureRecognizer(doubleTapGestureRecognizer) - + if #available(iOS 16.0, *) { + liveTextInteraction.isSupplementaryInterfaceHidden = true + imageView.addInteraction(liveTextInteraction) + } + delegate = self } @@ -129,6 +146,26 @@ extension MediaPreviewImageView { centerScrollViewContents() contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top) + + if #available(iOS 16.0, *) { + Task.detached(priority: .userInitiated) { + do { + let analysis = try await ImageAnalyzer.shared.analyze(image, configuration: ImageAnalyzer.Configuration([.text, .machineReadableCode])) + await MainActor.run { + self.liveTextInteraction.analysis = analysis + self.liveTextInteraction.preferredInteractionTypes = .automatic + if self.liveTextInteraction.isSupplementaryInterfaceHidden { + self.liveTextInteraction.setSupplementaryInterfaceHidden(false, animated: true) + } + + } + } catch { + await MainActor.run { + self.liveTextInteraction.preferredInteractionTypes = [] + } + } + } + } os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: setup image for container %s", ((#file as NSString).lastPathComponent), #line, #function, container.frame.debugDescription) } diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 127c4c0c0..1c00b3907 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -11,6 +11,7 @@ import Combine import MastodonAsset import MastodonLocalization import FLAnimatedImage +import VisionKit protocol MediaPreviewImageViewControllerDelegate: AnyObject { func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, tapGestureRecognizerDidTrigger tapGestureRecognizer: UITapGestureRecognizer) @@ -31,7 +32,7 @@ final class MediaPreviewImageViewController: UIViewController { let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer let longPressGestureRecognizer = UILongPressGestureRecognizer() - + deinit { os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) previewImageView.imageView.af.cancelImageRequest() @@ -42,7 +43,10 @@ extension MediaPreviewImageViewController { override func viewDidLoad() { super.viewDidLoad() - + + if #available(iOS 16.0, *) { + previewImageView.liveTextInteraction.delegate = self + } previewImageView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(previewImageView) NSLayoutConstraint.activate([ @@ -53,7 +57,9 @@ extension MediaPreviewImageViewController { ]) tapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.tapGestureRecognizerHandler(_:))) + tapGestureRecognizer.delegate = self longPressGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.longPressGestureRecognizerHandler(_:))) + longPressGestureRecognizer.delegate = self tapGestureRecognizer.require(toFail: previewImageView.doubleTapGestureRecognizer) tapGestureRecognizer.require(toFail: longPressGestureRecognizer) previewImageView.addGestureRecognizer(tapGestureRecognizer) @@ -105,10 +111,42 @@ extension MediaPreviewImageViewController { } +// MARK: - ImageAnalysisInteractionDelegate +@available(iOS 16.0, *) +extension MediaPreviewImageViewController: ImageAnalysisInteractionDelegate { + func contentView(for interaction: ImageAnalysisInteraction) -> UIView? { + view + } + + func presentingViewController(for interaction: ImageAnalysisInteraction) -> UIViewController? { + self + } +} + +// MARK: - UIGestureRecognizerDelegate +extension MediaPreviewImageViewController: UIGestureRecognizerDelegate { + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { + if #available(iOS 16.0, *) { + let location = touch.location(in: previewImageView.imageView) + let hasItem = previewImageView.liveTextInteraction.hasInteractiveItem(at: location) + return !hasItem + } else { + return true + } + } +} + // MARK: - UIContextMenuInteractionDelegate extension MediaPreviewImageViewController: UIContextMenuInteractionDelegate { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + + if #available(iOS 16.0, *) { + if previewImageView.liveTextInteraction.hasInteractiveItem(at: previewImageView.imageView.convert(location, from: previewImageView)) { + return nil + } + } + let previewProvider: UIContextMenuContentPreviewProvider = { () -> UIViewController? in return nil diff --git a/MastodonSDK/Sources/MastodonExtension/ImageAnalyzer.swift b/MastodonSDK/Sources/MastodonExtension/ImageAnalyzer.swift new file mode 100644 index 000000000..cf8a0f437 --- /dev/null +++ b/MastodonSDK/Sources/MastodonExtension/ImageAnalyzer.swift @@ -0,0 +1,13 @@ +// +// ImageAnalyzer.swift +// +// +// Created by Jed Fox on 2022-11-14. +// + +import VisionKit + +@available(iOS 16.0, *) +extension ImageAnalyzer { + public static let shared = ImageAnalyzer() +} From 5277ec191bb26b3e2ea87bf7cd28360e6ae1bc5f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 14 Nov 2022 21:50:38 -0500 Subject: [PATCH 017/733] Drop attempt to fade in the supplementary interface sometimes it just stayed hidden? --- .../Scene/MediaPreview/Image/MediaPreviewImageView.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift index cc31a9639..8432ddade 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift @@ -72,7 +72,6 @@ extension MediaPreviewImageView { doubleTapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageView.doubleTapGestureRecognizerHandler(_:))) imageView.addGestureRecognizer(doubleTapGestureRecognizer) if #available(iOS 16.0, *) { - liveTextInteraction.isSupplementaryInterfaceHidden = true imageView.addInteraction(liveTextInteraction) } @@ -154,10 +153,6 @@ extension MediaPreviewImageView { await MainActor.run { self.liveTextInteraction.analysis = analysis self.liveTextInteraction.preferredInteractionTypes = .automatic - if self.liveTextInteraction.isSupplementaryInterfaceHidden { - self.liveTextInteraction.setSupplementaryInterfaceHidden(false, animated: true) - } - } } catch { await MainActor.run { From 0687ef4f8eae50b3edc5647e9df522ba4875c8af Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 14 Nov 2022 21:52:16 -0500 Subject: [PATCH 018/733] Add support for tapping an image to hide all the chrome --- Mastodon/Coordinator/SceneCoordinator.swift | 2 +- .../MediaPreviewImageViewController.swift | 24 ++++++++++++----- .../MediaPreviewViewController.swift | 26 +++++++++++++++++-- .../MediaPreview/MediaPreviewViewModel.swift | 17 +++++++++++- .../MediaPreviewVideoViewController.swift | 6 +++++ 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 8a0825969..01fb744ce 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -339,7 +339,7 @@ extension SceneCoordinator { case .custom(let transitioningDelegate): viewController.modalPresentationStyle = .custom viewController.transitioningDelegate = transitioningDelegate - // viewController.modalPresentationCapturesStatusBarAppearance = true + viewController.modalPresentationCapturesStatusBarAppearance = true (splitViewController ?? presentingViewController)?.present(viewController, animated: true, completion: nil) case .customPush(let animated): diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 1c00b3907..513110d29 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -111,13 +111,19 @@ extension MediaPreviewImageViewController { } +extension MediaPreviewImageViewController: MediaPreviewPage { + func setShowingChrome(_ showingChrome: Bool) { + if #available(iOS 16.0, *) { + UIView.animate(withDuration: 0.3) { + self.previewImageView.liveTextInteraction.setSupplementaryInterfaceHidden(!showingChrome, animated: true) + } + } + } +} + // MARK: - ImageAnalysisInteractionDelegate @available(iOS 16.0, *) extension MediaPreviewImageViewController: ImageAnalysisInteractionDelegate { - func contentView(for interaction: ImageAnalysisInteraction) -> UIView? { - view - } - func presentingViewController(for interaction: ImageAnalysisInteraction) -> UIViewController? { self } @@ -128,8 +134,14 @@ extension MediaPreviewImageViewController: UIGestureRecognizerDelegate { func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { if #available(iOS 16.0, *) { let location = touch.location(in: previewImageView.imageView) - let hasItem = previewImageView.liveTextInteraction.hasInteractiveItem(at: location) - return !hasItem + // for tap gestures, only items that can be tapped are relevant + if gestureRecognizer is UITapGestureRecognizer { + return !previewImageView.liveTextInteraction.hasSupplementaryInterface(at: location) + && !previewImageView.liveTextInteraction.hasDataDetector(at: location) + } else { + // for long press, block out everything + return !previewImageView.liveTextInteraction.hasInteractiveItem(at: location) + } } else { return true } diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index c6552bcba..f3a59d0bb 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -137,6 +137,17 @@ extension MediaPreviewViewController { } } .store(in: &disposeBag) + + viewModel.$showingChrome + .receive(on: DispatchQueue.main) + .removeDuplicates() + .sink { [weak self] showingChrome in + UIView.animate(withDuration: 0.3) { + self?.setNeedsStatusBarAppearanceUpdate() + self?.closeButtonBackground.alpha = showingChrome ? 1 : 0 + } + } + .store(in: &disposeBag) // viewModel.$isPoping // .receive(on: DispatchQueue.main) @@ -153,6 +164,14 @@ extension MediaPreviewViewController { } +extension MediaPreviewViewController { + + override var prefersStatusBarHidden: Bool { + !viewModel.showingChrome + } + +} + extension MediaPreviewViewController { @objc private func closeButtonPressed(_ sender: UIButton) { @@ -239,8 +258,11 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { let location = tapGestureRecognizer.location(in: viewController.previewImageView.imageView) let isContainsTap = viewController.previewImageView.imageView.frame.contains(location) - guard !isContainsTap else { return } - dismiss(animated: true, completion: nil) + if isContainsTap { + self.viewModel.showingChrome.toggle() + } else { + dismiss(animated: true, completion: nil) + } } func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, longPressGestureRecognizerDidTrigger longPressGestureRecognizer: UILongPressGestureRecognizer) { diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift index c43d24945..3f60b19e5 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift @@ -12,6 +12,10 @@ import CoreDataStack import Pageboy import MastodonCore +protocol MediaPreviewPage: UIViewController { + func setShowingChrome(_ showingChrome: Bool) +} + final class MediaPreviewViewModel: NSObject { weak var mediaPreviewImageViewControllerDelegate: MediaPreviewImageViewControllerDelegate? @@ -22,9 +26,12 @@ final class MediaPreviewViewModel: NSObject { let transitionItem: MediaPreviewTransitionItem @Published var currentPage: Int + @Published var showingChrome = true // output let viewControllers: [UIViewController] + + private var disposeBag: Set = [] init( context: AppContext, @@ -34,7 +41,7 @@ final class MediaPreviewViewModel: NSObject { self.context = context self.item = item var currentPage = 0 - var viewControllers: [UIViewController] = [] + var viewControllers: [MediaPreviewPage] = [] switch item { case .attachment(let previewContext): currentPage = previewContext.initialIndex @@ -106,6 +113,14 @@ final class MediaPreviewViewModel: NSObject { self.currentPage = currentPage self.transitionItem = transitionItem super.init() + + for viewController in viewControllers { + self.$showingChrome + .sink { [weak viewController] showingChrome in + viewController?.setShowingChrome(showingChrome) + } + .store(in: &disposeBag) + } } } diff --git a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift index 7bdbbfed2..792854248 100644 --- a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift +++ b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift @@ -111,6 +111,12 @@ extension MediaPreviewVideoViewController { // } //} +extension MediaPreviewVideoViewController: MediaPreviewPage { + func setShowingChrome(_ showingChrome: Bool) { + // TODO: does this do anything? + } +} + // MARK: - AVPlayerViewControllerDelegate extension MediaPreviewVideoViewController: AVPlayerViewControllerDelegate { From 527f6f0dfae1a0469648a7c86dabd64a98e65644 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 15 Nov 2022 06:58:43 -0500 Subject: [PATCH 019/733] Adjustments for new i18n workflow --- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- .../MastodonLocalization/Resources/en.lproj/Localizable.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 7434a34a2..25f06ad83 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notifications": "Notifications", + "notification": "Notification", "profile": "Profile" }, "keyboard": { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 75b935422..07ccd2c1b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -131,7 +131,7 @@ Please check your internet connection."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; "Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Home"; -"Common.Controls.Tabs.Notifications" = "Notifications"; +"Common.Controls.Tabs.Notification" = "Notification"; "Common.Controls.Tabs.Profile" = "Profile"; "Common.Controls.Tabs.Search" = "Search"; "Common.Controls.Timeline.Filtered" = "Filtered"; From 60efe4f02320b5005554a8030e09f9d8759a0776 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 15 Nov 2022 13:13:22 -0500 Subject: [PATCH 020/733] Fix status bar when dismissing --- ...tToMediaPreviewViewControllerAnimatedTransitioning.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index 5381feb0d..de2cec6bf 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -131,6 +131,12 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { } return animator } + + if let toVC = transitionContext.viewController(forKey: .to) { + animator.addCompletion { _ in + toVC.setNeedsStatusBarAppearanceUpdate() + } + } // update close button UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { From ff5a0876c8cee61b341f8a932330c5184bb22098 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 15 Nov 2022 13:35:33 -0500 Subject: [PATCH 021/733] Change childForStatusBarStyle --- .../AdaptiveStatusBarStyleNavigationController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift index 80df8938e..88441f9ad 100644 --- a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift +++ b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift @@ -14,7 +14,7 @@ class AdaptiveStatusBarStyleNavigationController: UINavigationController { // Make status bar style adaptive for child view controller // SeeAlso: `modalPresentationCapturesStatusBarAppearance` override var childForStatusBarStyle: UIViewController? { - visibleViewController + topViewController } } From 675df849e3a2c4469fc63db7204b920148770ad7 Mon Sep 17 00:00:00 2001 From: woxtu Date: Wed, 16 Nov 2022 12:21:08 +0900 Subject: [PATCH 022/733] Remove redundant nil coalescing --- Mastodon/Scene/Settings/Cell/SettingsToggleTableViewCell.swift | 2 +- .../Sources/MastodonUI/View/Content/StatusView+ViewModel.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/Settings/Cell/SettingsToggleTableViewCell.swift b/Mastodon/Scene/Settings/Cell/SettingsToggleTableViewCell.swift index 4926dbfce..05d5ecea2 100644 --- a/Mastodon/Scene/Settings/Cell/SettingsToggleTableViewCell.swift +++ b/Mastodon/Scene/Settings/Cell/SettingsToggleTableViewCell.swift @@ -86,7 +86,7 @@ extension SettingsToggleTableViewCell { return nil default: // set tint black for Light Mode - return self.contentView.window?.tintColor ?? nil + return self.contentView.window?.tintColor } }() } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 416226cbb..bb866331b 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -468,7 +468,7 @@ extension StatusView.ViewModel { pollCountdownDescription ) .sink { pollVoteDescription, pollCountdownDescription in - statusView.pollVoteCountLabel.text = pollVoteDescription ?? "-" + statusView.pollVoteCountLabel.text = pollVoteDescription statusView.pollCountdownLabel.text = pollCountdownDescription ?? "-" } .store(in: &disposeBag) From 5c508dfce0b256fac84d9d01cd9f310adecdb6f2 Mon Sep 17 00:00:00 2001 From: David Godfrey Date: Thu, 17 Nov 2022 00:18:49 +0000 Subject: [PATCH 023/733] Sort emoji alphabetically, and into sections --- .../ComposeContentViewModel+DataSource.swift | 71 +++++++++++++++---- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift index abbfe0e61..9430d68b3 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift @@ -7,6 +7,7 @@ import UIKit import MastodonCore +import MastodonSDK import CoreDataStack import UIHostingConfigurationBackport @@ -111,28 +112,68 @@ extension ComposeContentViewModel { context: context ) self.customEmojiPickerDiffableDataSource = diffableDataSource - + let domain = authContext.mastodonAuthenticationBox.domain.uppercased() customEmojiViewModel?.emojis - .receive(on: DispatchQueue.main) - .sink { [weak self, weak diffableDataSource] emojis in - guard let _ = self else { return } - guard let diffableDataSource = diffableDataSource else { return } + // Don't block the main queue + .receive(on: DispatchQueue.global(qos: .userInteractive)) + // Sort emojis + .map({ (emojis) -> [Mastodon.Entity.Emoji] in + return emojis.sorted { a, b in + a.shortcode.lowercased() < b.shortcode.lowercased() + } + }) + // Collate emojis into categories + .map({ (emojis) -> (noCategory: [Mastodon.Entity.Emoji], categorised: [String:[Mastodon.Entity.Emoji]]) in + let emojiMap: (noCategory: [Mastodon.Entity.Emoji], categorised: [String:[Mastodon.Entity.Emoji]]) = { + var noCategory = [Mastodon.Entity.Emoji]() + var categorised = [String:[Mastodon.Entity.Emoji]]() + + for emoji in emojis where emoji.visibleInPicker { + if let category = emoji.category { + var categoryArray = categorised[category] ?? [Mastodon.Entity.Emoji]() + categoryArray.append(emoji) + categorised[category] = categoryArray + } else { + noCategory.append(emoji) + } + } + + return ( + noCategory, + categorised + ) + }() + return emojiMap + }) + // Build snapshot from emoji map + .map({ (emojiMap) -> NSDiffableDataSourceSnapshot in + var snapshot = NSDiffableDataSourceSnapshot() let customEmojiSection = CustomEmojiPickerSection.emoji(name: domain) snapshot.appendSections([customEmojiSection]) - let items: [CustomEmojiPickerItem] = { - var items = [CustomEmojiPickerItem]() - for emoji in emojis where emoji.visibleInPicker { - let attribute = CustomEmojiPickerItem.CustomEmojiAttribute(emoji: emoji) - let item = CustomEmojiPickerItem.emoji(attribute: attribute) - items.append(item) + snapshot.appendItems(emojiMap.noCategory.map({ emoji in + CustomEmojiPickerItem.emoji(attribute: CustomEmojiPickerItem.CustomEmojiAttribute(emoji: emoji)) + }), toSection: customEmojiSection) + emojiMap.categorised.keys.sorted().forEach { category in + let section = CustomEmojiPickerSection.emoji(name: category) + snapshot.appendSections([section]) + if let items = emojiMap.categorised[category] { + snapshot.appendItems(items.map({ emoji in + CustomEmojiPickerItem.emoji(attribute: CustomEmojiPickerItem.CustomEmojiAttribute(emoji: emoji)) + }), toSection: section) } - return items - }() - snapshot.appendItems(items, toSection: customEmojiSection) - + } + + return snapshot + }) + // Apply snapshot + .receive(on: DispatchQueue.main) + .sink { [weak self, weak diffableDataSource] snapshot in + guard let _ = self else { return } + guard let diffableDataSource = diffableDataSource else { return } + diffableDataSource.apply(snapshot) } .store(in: &disposeBag) From c6826542f9293ecec152c1fa1a3d8c8c5a07952d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 16 Nov 2022 20:26:26 -0500 Subject: [PATCH 024/733] =?UTF-8?q?Add=20a=20=E2=80=9CJoined=E2=80=9D=20ce?= =?UTF-8?q?ll=20to=20the=20top=20of=20the=20About=20tab=20to=20match=20the?= =?UTF-8?q?=20web=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input/Base.lproj/app.json | 1 + Localization/app.json | 1 + .../Diffable/Profile/ProfileFieldItem.swift | 2 +- .../Profile/ProfileFieldSection.swift | 74 +++++++++---------- .../ProfileAboutViewModel+Diffable.swift | 26 ++++--- .../Profile/About/ProfileAboutViewModel.swift | 6 ++ .../Generated/Strings.swift | 2 + .../Resources/Base.lproj/Localizable.strings | 1 + 8 files changed, 62 insertions(+), 51 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 96b2150ce..af3e7c6ae 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -449,6 +449,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", diff --git a/Localization/app.json b/Localization/app.json index 96b2150ce..af3e7c6ae 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -449,6 +449,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", diff --git a/Mastodon/Diffable/Profile/ProfileFieldItem.swift b/Mastodon/Diffable/Profile/ProfileFieldItem.swift index e33a2f883..37d08bc52 100644 --- a/Mastodon/Diffable/Profile/ProfileFieldItem.swift +++ b/Mastodon/Diffable/Profile/ProfileFieldItem.swift @@ -11,10 +11,10 @@ import MastodonSDK import MastodonMeta enum ProfileFieldItem: Hashable { + case createdAt(date: Date) case field(field: FieldValue) case editField(field: FieldValue) case addEntry - case noResult } extension ProfileFieldItem { diff --git a/Mastodon/Diffable/Profile/ProfileFieldSection.swift b/Mastodon/Diffable/Profile/ProfileFieldSection.swift index 6e57e6af9..8a68cc51d 100644 --- a/Mastodon/Diffable/Profile/ProfileFieldSection.swift +++ b/Mastodon/Diffable/Profile/ProfileFieldSection.swift @@ -33,44 +33,57 @@ extension ProfileFieldSection { collectionView.register(ProfileFieldCollectionViewHeaderFooterView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: ProfileFieldCollectionViewHeaderFooterView.footerReuseIdentifer) let fieldCellRegistration = UICollectionView.CellRegistration { cell, indexPath, item in - guard case let .field(field) = item else { return } + let key, value: String + let emojiMeta: MastodonContent.Emojis + let verified: Bool + + switch item { + case .field(field: let field): + key = field.name.value + value = field.value.value + emojiMeta = field.emojiMeta + verified = field.verifiedAt.value != nil + case .createdAt(date: let date): + key = L10n.Scene.Profile.Fields.joined + let formatter = DateFormatter() + formatter.dateStyle = .medium + formatter.timeStyle = .none + value = formatter.string(from: date) + emojiMeta = [:] + verified = false + default: return + } // set key do { - let mastodonContent = MastodonContent(content: field.name.value, emojis: field.emojiMeta) + let mastodonContent = MastodonContent(content: key, emojis: emojiMeta) let metaContent = try MastodonMetaContent.convert(document: mastodonContent) cell.keyMetaLabel.configure(content: metaContent) } catch { - let content = PlaintextMetaContent(string: field.name.value) + let content = PlaintextMetaContent(string: key) cell.keyMetaLabel.configure(content: content) } // set value + let linkColor = verified ? Asset.Scene.Profile.About.bioAboutFieldVerifiedLink.color : Asset.Colors.brand.color do { - let mastodonContent = MastodonContent(content: field.value.value, emojis: field.emojiMeta) + let mastodonContent = MastodonContent(content: value, emojis: emojiMeta) let metaContent = try MastodonMetaContent.convert(document: mastodonContent) - cell.valueMetaLabel.linkAttributes[.foregroundColor] = Asset.Colors.brand.color - if field.verifiedAt.value != nil { - cell.valueMetaLabel.linkAttributes[.foregroundColor] = Asset.Scene.Profile.About.bioAboutFieldVerifiedLink.color - } + cell.valueMetaLabel.linkAttributes[.foregroundColor] = linkColor cell.valueMetaLabel.configure(content: metaContent) } catch { - let content = PlaintextMetaContent(string: field.value.value) + let content = PlaintextMetaContent(string: value) + cell.valueMetaLabel.linkAttributes[.foregroundColor] = linkColor cell.valueMetaLabel.configure(content: content) } // set background var backgroundConfiguration = UIBackgroundConfiguration.listPlainCell() - backgroundConfiguration.backgroundColor = UIColor.secondarySystemBackground - if (field.verifiedAt.value != nil) { - backgroundConfiguration.backgroundColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedBackground.color - } + backgroundConfiguration.backgroundColor = verified ? Asset.Scene.Profile.About.bioAboutFieldVerifiedBackground.color : UIColor.secondarySystemBackground cell.backgroundConfiguration = backgroundConfiguration // set checkmark and edit menu label - cell.checkmark.isHidden = true - cell.checkmarkPopoverString = nil - if let verifiedAt = field.verifiedAt.value { + if case .field(let field) = item, let verifiedAt = field.verifiedAt.value { cell.checkmark.isHidden = false let formatter = DateFormatter() formatter.dateStyle = .medium @@ -78,6 +91,9 @@ extension ProfileFieldSection { let dateString = formatter.string(from: verifiedAt) cell.checkmark.accessibilityLabel = L10n.Scene.Profile.Fields.Verified.long(dateString) cell.checkmarkPopoverString = L10n.Scene.Profile.Fields.Verified.short(dateString) + } else { + cell.checkmark.isHidden = true + cell.checkmarkPopoverString = nil } cell.delegate = configuration.profileFieldCollectionViewCellDelegate @@ -128,26 +144,10 @@ extension ProfileFieldSection { } cell.backgroundConfiguration = backgroundConfiguration } - - let noResultCellRegistration = UICollectionView.CellRegistration { cell, indexPath, item in - guard case .noResult = item else { return } - - var contentConfiguration = cell.defaultContentConfiguration() - contentConfiguration.text = L10n.Scene.Search.Searching.EmptyState.noResults // FIXME: - contentConfiguration.textProperties.alignment = .center - cell.contentConfiguration = contentConfiguration - - - var backgroundConfiguration = UIBackgroundConfiguration.listPlainCell() - backgroundConfiguration.backgroundColorTransformer = .init { _ in - return .secondarySystemBackground - } - cell.backgroundConfiguration = backgroundConfiguration - } - + let dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in switch item { - case .field: + case .field, .createdAt: return collectionView.dequeueConfiguredReusableCell( using: fieldCellRegistration, for: indexPath, @@ -165,12 +165,6 @@ extension ProfileFieldSection { for: indexPath, item: item ) - case .noResult: - return collectionView.dequeueConfiguredReusableCell( - using: noResultCellRegistration, - for: indexPath, - item: item - ) } } diff --git a/Mastodon/Scene/Profile/About/ProfileAboutViewModel+Diffable.swift b/Mastodon/Scene/Profile/About/ProfileAboutViewModel+Diffable.swift index 0a11a71f6..eb7a6aaae 100644 --- a/Mastodon/Scene/Profile/About/ProfileAboutViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/About/ProfileAboutViewModel+Diffable.swift @@ -50,23 +50,33 @@ extension ProfileAboutViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) diffableDataSource.apply(snapshot) - - Publishers.CombineLatest4( + + let fields = Publishers.CombineLatest3( $isEditing.removeDuplicates(), profileInfo.$fields.removeDuplicates(), - profileInfoEditing.$fields.removeDuplicates(), + profileInfoEditing.$fields.removeDuplicates() + ).map { isEditing, displayFields, editingFields in + isEditing ? editingFields : displayFields + } + + + Publishers.CombineLatest4( + $isEditing.removeDuplicates(), + $createdAt.removeDuplicates(), + fields, $emojiMeta.removeDuplicates() ) .throttle(for: 0.3, scheduler: DispatchQueue.main, latest: true) - .sink { [weak self] isEditing, displayFields, editingFields, emojiMeta in + .sink { [weak self] isEditing, createdAt, fields, emojiMeta in guard let self = self else { return } guard let diffableDataSource = self.diffableDataSource else { return } var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) - let fields: [ProfileFieldItem.FieldValue] = isEditing ? editingFields : displayFields - var items: [ProfileFieldItem] = fields.map { field in + var items: [ProfileFieldItem] = [ + .createdAt(date: createdAt), + ] + fields.map { field in if isEditing { return ProfileFieldItem.editField(field: field) } else { @@ -78,10 +88,6 @@ extension ProfileAboutViewModel { items.append(.addEntry) } - if !isEditing, items.isEmpty { - items.append(.noResult) - } - snapshot.appendItems(items, toSection: .main) diffableDataSource.apply(snapshot, animatingDifferences: false, completion: nil) diff --git a/Mastodon/Scene/Profile/About/ProfileAboutViewModel.swift b/Mastodon/Scene/Profile/About/ProfileAboutViewModel.swift index 044894b8a..8ab427c39 100644 --- a/Mastodon/Scene/Profile/About/ProfileAboutViewModel.swift +++ b/Mastodon/Scene/Profile/About/ProfileAboutViewModel.swift @@ -31,6 +31,7 @@ final class ProfileAboutViewModel { @Published var fields: [MastodonField] = [] @Published var emojiMeta: MastodonContent.Emojis = [:] + @Published var createdAt: Date = Date() init(context: AppContext) { self.context = context @@ -46,6 +47,11 @@ final class ProfileAboutViewModel { .compactMap { $0 } .flatMap { $0.publisher(for: \.fields) } .assign(to: &$fields) + + $user + .compactMap { $0 } + .flatMap { $0.publisher(for: \.createdAt) } + .assign(to: &$createdAt) Publishers.CombineLatest( $fields, diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index ee56f9e31..2d33abe5d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -745,6 +745,8 @@ public enum L10n { public enum Fields { /// Add Row public static let addRow = L10n.tr("Localizable", "Scene.Profile.Fields.AddRow", fallback: "Add Row") + /// Joined + public static let joined = L10n.tr("Localizable", "Scene.Profile.Fields.Joined", fallback: "Joined") public enum Placeholder { /// Content public static let content = L10n.tr("Localizable", "Scene.Profile.Fields.Placeholder.Content", fallback: "Content") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 2a3f1efbf..1b81a15b6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -268,6 +268,7 @@ uploaded to Mastodon."; "Scene.Profile.Dashboard.Following" = "following"; "Scene.Profile.Dashboard.Posts" = "posts"; "Scene.Profile.Fields.AddRow" = "Add Row"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Content"; "Scene.Profile.Fields.Placeholder.Label" = "Label"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; From c34f0b4f11da34c1381efa111f1d209269c65cfb Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 16 Nov 2022 20:44:55 -0500 Subject: [PATCH 025/733] =?UTF-8?q?Color=20the=20verified=20link=E2=80=99s?= =?UTF-8?q?=20header=20green=20as=20well=20to=20match=20the=20website?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Profile/ProfileFieldSection.swift | 5 ++- .../Cell/ProfileFieldCollectionViewCell.swift | 2 +- .../Contents.json | 38 ------------------- .../Contents.json | 0 .../MastodonAsset/Generated/Assets.swift | 3 +- 5 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.link.colorset/Contents.json rename MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/{bio.about.field.verified.checkmark.colorset => bio.about.field.verified.text.colorset}/Contents.json (100%) diff --git a/Mastodon/Diffable/Profile/ProfileFieldSection.swift b/Mastodon/Diffable/Profile/ProfileFieldSection.swift index 8a68cc51d..10946915d 100644 --- a/Mastodon/Diffable/Profile/ProfileFieldSection.swift +++ b/Mastodon/Diffable/Profile/ProfileFieldSection.swift @@ -55,17 +55,20 @@ extension ProfileFieldSection { } // set key + let keyColor = verified ? Asset.Scene.Profile.About.bioAboutFieldVerifiedText.color : Asset.Colors.Label.secondary.color do { let mastodonContent = MastodonContent(content: key, emojis: emojiMeta) let metaContent = try MastodonMetaContent.convert(document: mastodonContent) + cell.keyMetaLabel.textAttributes[.foregroundColor] = keyColor cell.keyMetaLabel.configure(content: metaContent) } catch { let content = PlaintextMetaContent(string: key) +// cell.keyMetaLabel.textAttributes[.foregroundColor] = keyColor cell.keyMetaLabel.configure(content: content) } // set value - let linkColor = verified ? Asset.Scene.Profile.About.bioAboutFieldVerifiedLink.color : Asset.Colors.brand.color + let linkColor = verified ? Asset.Scene.Profile.About.bioAboutFieldVerifiedText.color : Asset.Colors.brand.color do { let mastodonContent = MastodonContent(content: value, emojis: emojiMeta) let metaContent = try MastodonMetaContent.convert(document: mastodonContent) diff --git a/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift b/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift index 1ed76a485..59ad59139 100644 --- a/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift +++ b/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift @@ -58,7 +58,7 @@ extension ProfileFieldCollectionViewCell { private func _init() { // Setup colors - checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedCheckmark.color; + checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedText.color; // Setup gestures tapGesture.addTarget(self, action: #selector(ProfileFieldCollectionViewCell.didTapCheckmark(_:))) diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.link.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.link.colorset/Contents.json deleted file mode 100644 index f5112f04f..000000000 --- a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.link.colorset/Contents.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "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 - } -} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.checkmark.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.text.colorset/Contents.json similarity index 100% rename from MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.checkmark.colorset/Contents.json rename to MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Profile/About/bio.about.field.verified.text.colorset/Contents.json diff --git a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift index 155227685..5665493d9 100644 --- a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift +++ b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift @@ -173,8 +173,7 @@ public enum Asset { public enum Profile { public enum About { public static let bioAboutFieldVerifiedBackground = ColorAsset(name: "Scene/Profile/About/bio.about.field.verified.background") - public static let bioAboutFieldVerifiedCheckmark = ColorAsset(name: "Scene/Profile/About/bio.about.field.verified.checkmark") - public static let bioAboutFieldVerifiedLink = ColorAsset(name: "Scene/Profile/About/bio.about.field.verified.link") + public static let bioAboutFieldVerifiedText = ColorAsset(name: "Scene/Profile/About/bio.about.field.verified.text") } public enum Banner { public static let bioEditBackgroundGray = ColorAsset(name: "Scene/Profile/Banner/bio.edit.background.gray") From 1d6d059718fa8fcfc7cfb76e15e5e245786e72ae Mon Sep 17 00:00:00 2001 From: CMK Date: Fri, 22 Jul 2022 17:48:04 +0800 Subject: [PATCH 026/733] cherry-pick: 79a76b39c657fe5ecd63ead48b756e82738e7b4d --- Documentation/How-it-works.md | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Documentation/How-it-works.md diff --git a/Documentation/How-it-works.md b/Documentation/How-it-works.md new file mode 100644 index 000000000..a1e12b186 --- /dev/null +++ b/Documentation/How-it-works.md @@ -0,0 +1,75 @@ +# How it works +The app is currently built for iOS and iPadOS. We use the MVVM architecture to construct the whole app. Some design detail may not be the best practice and welcome any suggestions for improvements. + +## Data +A typical status timeline fetches results from the database using a predicate that specifies active account-related entities displayed. Then table view data source dequeues an item to configure the view. Likes many other MVVM applications. The app binds the Core Data entity to view via Combine publisher. Because the RunLoop dispatch drawing on the next loop. So we could return quickly. + +## Layout +A timeline has many posts and each post has many components. For example avatar, name, username, timestamp, content, media, and toolbar. The app uses `AutoLayout` with `UIStackView` to place it and control whether it should hide or not. + +## Performance +Although it's easily loading timeline with hundreds of thousands of entities due to the Core Data fault mechanism. Some old devices may have slow performance when I/O bottleneck. There are two potential profile chances for entities preload fulfill and background drawing layout. + +## SwiftUI +Some view models already migrate to `@Published` annotated output. It's future-proof support for SwiftUI. There are some views already transformed to `SwiftUI` likes `MastodonRegisterView` and `ReportReasonView`. + +# Take it apart +## Targets +The app builds with those targets: + +- Mastodon: the app itself +- NotificationService: E2E push notification service +- ShareActionExtension: iOS share action +- MastodonIntent: Siri shortcuts +- AppShared: SwiftPM dependency resolve + + +## MastodonSDK +There is a self-hosted Swift Package that contains the common libraries to build this app. + +- CoreDataStack: Core Data model definition and util methods +- MastodonAsset: image and font assets +- MastodonCommon: store App Group ID +- MastodonExtension: system API extension utility +- MastodonLocalization: i18n resources +- MastodonSDK: Mastodon API client +- MastodonUI: App UI components + +#### CoreDataStack +App uses Core Data as the backend to persist all entitles from the server. So the app has the capability to keep the timeline and notifications. Another reason for using a database is it makes the app could respond to entity changes between different sources. For example, a user could skim in the home timeline and then interact with the same post on other pages with favorite or reblog actions. Core Data will handle the property modifications and notify the home timeline to update the view. + +To simplify the database operations. There is only one persistent store for all accounts. We use `domain` to identify entity for different servers (a.k.a instance). Do not mix the `domain` with the Mastodon remote server name. The domain is `mastodon.online` whatever the post (e.g. post at `mstdn.jp`) and friends from for an account sign in `mastodon.online`. Also, do not only rely on `id` because it has conflict potential in others `domain`. + +The app use one stack two context Core Data setup. There is one main managed object context for UI displaying and another background managed context for entities creating and updating. We assert the background context performs in a queue. But derive a new background context for long-time database operation to avoid concurrency persistent conflict issues should be considered. + +#### MastodonAsset +Sourcery powered assets packet. + +#### MastodonCommon +Shared code for preference and configuration. + +#### MastodonExtension +Utility extension codes for SDK. + +#### MastodonLocalization +Sourcery powered i18n packet. + +#### MastodonSDK +Mastodon API wrapper with Combine style API. + +#### MastodonUI +Mastodon app UI components. + +## NotificationService +Mastodon server accepts push notification register and we use the [toot-relay](https://github.com/DagAgren/toot-relay) to pass the server notifications to APNs. The message is E2E encrypted. The app will create an on-device private key for notification and save it into the keychain. + +When the push notification is incoming. iOS will spawn our NotificationService extension to handle the message. At that time the message is decrypted and displayed as a banner or in-app silent notification event when the app is in the foreground. All the notification count and deep-link logic are handled by the main app. + +## ShareActionExtension +The iOS Share Extension allows users to share links or media from other apps. The app uses the UIKit implementation. For simplifying we using the SwiftUI implementing a replica one but with fewer features. + +## MastodonIntent +iOS Siri shortcut supports. It allows iOS directly publish posts via Shortcut without app launching. + +## AppShared +A framework for SwiftPM packet dependency resolve. Also, for CocoaPods-Key integration but we migrate to Arkana now. From 3b1e7ed3909d6084352176b7347f4de9e186ab8c Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 17 Nov 2022 23:29:42 +0800 Subject: [PATCH 027/733] chore: update doc for how-it-works --- Documentation/How-it-works.md | 49 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/Documentation/How-it-works.md b/Documentation/How-it-works.md index a1e12b186..1a1969623 100644 --- a/Documentation/How-it-works.md +++ b/Documentation/How-it-works.md @@ -1,14 +1,17 @@ # How it works -The app is currently built for iOS and iPadOS. We use the MVVM architecture to construct the whole app. Some design detail may not be the best practice and welcome any suggestions for improvements. +The app is currently build for iOS and iPadOS. We use the MVVM architecture to construct the whole app. Some design detail may not be the best practice. And any suggestions for improvements are welcome. ## Data -A typical status timeline fetches results from the database using a predicate that specifies active account-related entities displayed. Then table view data source dequeues an item to configure the view. Likes many other MVVM applications. The app binds the Core Data entity to view via Combine publisher. Because the RunLoop dispatch drawing on the next loop. So we could return quickly. +A typical status timeline fetches results from the database using a predicate that fetch the active account's entities. Then data source dequeues an item then configure the view. Likes many other MVVM applications. The app binds the Core Data entity to view via Combine publisher. Because the RunLoop dispatch drawing on the next loop. So we could return quickly. ## Layout -A timeline has many posts and each post has many components. For example avatar, name, username, timestamp, content, media, and toolbar. The app uses `AutoLayout` with `UIStackView` to place it and control whether it should hide or not. +A timeline has many posts and each post has many components. For example avatar, name, username, timestamp, content, media, toolbar and e.t.c. The app uses `AutoLayout` with `UIStackView` to place it and control whether it should hide or not. ## Performance -Although it's easily loading timeline with hundreds of thousands of entities due to the Core Data fault mechanism. Some old devices may have slow performance when I/O bottleneck. There are two potential profile chances for entities preload fulfill and background drawing layout. +Although it's easily loading timeline with hundreds of thousands of entities due to the Core Data fault mechanism. Some old devices may have slow performance when I/O bottleneck. There are three potential profile chances for entities: +- preload fulfill +- layout in background +- limit the data fetching ## SwiftUI Some view models already migrate to `@Published` annotated output. It's future-proof support for SwiftUI. There are some views already transformed to `SwiftUI` likes `MastodonRegisterView` and `ReportReasonView`. @@ -21,8 +24,6 @@ The app builds with those targets: - NotificationService: E2E push notification service - ShareActionExtension: iOS share action - MastodonIntent: Siri shortcuts -- AppShared: SwiftPM dependency resolve - ## MastodonSDK There is a self-hosted Swift Package that contains the common libraries to build this app. @@ -30,29 +31,52 @@ There is a self-hosted Swift Package that contains the common libraries to build - CoreDataStack: Core Data model definition and util methods - MastodonAsset: image and font assets - MastodonCommon: store App Group ID +- MastodonCore: the logic for the app - MastodonExtension: system API extension utility - MastodonLocalization: i18n resources - MastodonSDK: Mastodon API client - MastodonUI: App UI components #### CoreDataStack -App uses Core Data as the backend to persist all entitles from the server. So the app has the capability to keep the timeline and notifications. Another reason for using a database is it makes the app could respond to entity changes between different sources. For example, a user could skim in the home timeline and then interact with the same post on other pages with favorite or reblog actions. Core Data will handle the property modifications and notify the home timeline to update the view. +App uses Core Data as the backend to persist all entitles from the server. So the app has the capability to keep the timeline and notifications. Another reason for using a database is it makes the app could respond to entity changes between different sources. For example, a user could skim in the home timeline and then interact with the same post on other pages with favorite or reblog action. Core Data will handle the property modifications and notify the home timeline to update the view. -To simplify the database operations. There is only one persistent store for all accounts. We use `domain` to identify entity for different servers (a.k.a instance). Do not mix the `domain` with the Mastodon remote server name. The domain is `mastodon.online` whatever the post (e.g. post at `mstdn.jp`) and friends from for an account sign in `mastodon.online`. Also, do not only rely on `id` because it has conflict potential in others `domain`. +To simplify the database operations. There is only one persistent store for all accounts. We use `domain` to identify entity for different servers (a.k.a instance). Do not mix the `domain` with the Mastodon remote server name. For example. The domain is `mastodon.online` whereever the post (e.g. post come from `mstdn.jp`) and friends from for the account sign in `mastodon.online`. Also, do not only rely on `id` because it has conflict potential between different `domain`. The unique predicate is `domain` + `id`. -The app use one stack two context Core Data setup. There is one main managed object context for UI displaying and another background managed context for entities creating and updating. We assert the background context performs in a queue. But derive a new background context for long-time database operation to avoid concurrency persistent conflict issues should be considered. +The app use "One stack, two context" setup. There is one main managed object context for UI displaying and another background managed context for entities creating and updating. We assert the background context performs in a queue. Also, the app could accept mulitple background context model. Then the flag `-com.apple.CoreData.ConcurrencyDebug 1` will be usful. + +###### How to create a new Entity +First, select the `CoreData.xcdatamodeld` file and in menu `Editor > Add Model Version…` to create a new version. Make sure active the new version in the inspect panel. e.g. `Model Version. Current > "Core Data 5"` + +Then use the `Add Entity` button create new Entity. +1. Give a name in data model inspect panel. +2. Also, set the `Module` to `CoreDataStack`. +3. Set the `Codegen` to `Manual/None`. We use `Sourery` generates the template code. +4. Create the `Entity.swift` file and declear the properties and relationships. + +###### How to add or remove property for Entity +We using the Core Data lightweight migration. Please check the rules detail [here](https://developer.apple.com/documentation/coredata/using_lightweight_migration). And keep in mind that we using two-way relationship. And a relationship could be one-to-one, one-to-many/many-to-one. + +Tip: + +Please check the `Soucery` and use that generates getter and setter for properties and relationships. It's could save you time. To take the benefit from the dynamic property. We can declare a raw value property and then use compute property to construct the struct we want (e.g. `Feed.acct`). Or control the primitive by hand and declare the mirror type for this value (e.g `Status.attachments`). + +###### How to persist the Entity +Please check the `Persistence+Status.swift`. We follow the pattern: migrate the old one if exists. Otherwise, create a new one. (Maybe some improvements could be adopted?) #### MastodonAsset -Sourcery powered assets packet. +Sourcery powered assets package. #### MastodonCommon Shared code for preference and configuration. +### MastodonCore +The core logic to drive the app. + #### MastodonExtension Utility extension codes for SDK. #### MastodonLocalization -Sourcery powered i18n packet. +Sourcery powered i18n package. #### MastodonSDK Mastodon API wrapper with Combine style API. @@ -70,6 +94,3 @@ The iOS Share Extension allows users to share links or media from other apps. Th ## MastodonIntent iOS Siri shortcut supports. It allows iOS directly publish posts via Shortcut without app launching. - -## AppShared -A framework for SwiftPM packet dependency resolve. Also, for CocoaPods-Key integration but we migrate to Arkana now. From 75edb750714ac37d2f9c2b25aea54f64a57264cb Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 17 Nov 2022 23:39:46 +0800 Subject: [PATCH 028/733] chore: update the describe for the share extension --- Documentation/How-it-works.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/How-it-works.md b/Documentation/How-it-works.md index 1a1969623..6b48159e5 100644 --- a/Documentation/How-it-works.md +++ b/Documentation/How-it-works.md @@ -90,7 +90,7 @@ Mastodon server accepts push notification register and we use the [toot-relay](h When the push notification is incoming. iOS will spawn our NotificationService extension to handle the message. At that time the message is decrypted and displayed as a banner or in-app silent notification event when the app is in the foreground. All the notification count and deep-link logic are handled by the main app. ## ShareActionExtension -The iOS Share Extension allows users to share links or media from other apps. The app uses the UIKit implementation. For simplifying we using the SwiftUI implementing a replica one but with fewer features. +The iOS Share Extension allows users to share links or media from other apps. The app uses the same implementation for the main app and the share extension. Then different is less available memoery for extension so maybe some memory bounded task could crash the app. (Plesae file the issue) ## MastodonIntent iOS Siri shortcut supports. It allows iOS directly publish posts via Shortcut without app launching. From e2e93bdaf0dfd606b776d88d97075a5a25d891e7 Mon Sep 17 00:00:00 2001 From: Stefan Painhapp <4242986+painhapp@users.noreply.github.com> Date: Fri, 18 Nov 2022 03:53:52 +0900 Subject: [PATCH 029/733] #607 Use safe areas for image preview --- .../Image/MediaPreviewImageViewController.swift | 8 ++++---- ...oMediaPreviewViewControllerAnimatedTransitioning.swift | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 127c4c0c0..e28249312 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -46,10 +46,10 @@ extension MediaPreviewImageViewController { previewImageView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(previewImageView) NSLayoutConstraint.activate([ - previewImageView.frameLayoutGuide.topAnchor.constraint(equalTo: view.topAnchor), - previewImageView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor), - previewImageView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor), - previewImageView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor), + previewImageView.frameLayoutGuide.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + previewImageView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + previewImageView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), + previewImageView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), ]) tapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.tapGestureRecognizerHandler(_:))) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index 5381feb0d..8d6549b60 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -65,7 +65,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { let initialFrame = transitionItem.initialFrame ?? toViewEndFrame let transitionTargetFrame: CGRect = { let aspectRatio = transitionItem.aspectRatio ?? CGSize(width: initialFrame.width, height: initialFrame.height) - return AVMakeRect(aspectRatio: aspectRatio, insideRect: toView.bounds) + return AVMakeRect(aspectRatio: aspectRatio, insideRect: toView.bounds.inset(by: toView.safeAreaInsets)) }() let transitionImageView: UIImageView = { let imageView = UIImageView(frame: transitionContext.containerView.convert(initialFrame, from: nil)) From 7ab62394de1c5d6964cb354f676048ba193d8d67 Mon Sep 17 00:00:00 2001 From: Stefan Painhapp <4242986+painhapp@users.noreply.github.com> Date: Fri, 18 Nov 2022 19:07:44 +0900 Subject: [PATCH 030/733] Handle safe areas for image preview --- .../Image/MediaPreviewImageView.swift | 16 ++-------------- .../Image/MediaPreviewImageViewController.swift | 8 ++++---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift index 05f2ce70f..bb7d2d49f 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift @@ -112,23 +112,14 @@ extension MediaPreviewImageView { // reset to normal zoomScale = minimumZoomScale - let imageViewSize = AVMakeRect(aspectRatio: image.size, insideRect: container.bounds).size - let imageContentInset: UIEdgeInsets = { - if imageViewSize.width == container.bounds.width { - return UIEdgeInsets(top: 0.5 * (container.bounds.height - imageViewSize.height), left: 0, bottom: 0, right: 0) - } else { - return UIEdgeInsets(top: 0, left: 0.5 * (container.bounds.width - imageViewSize.width), bottom: 0, right: 0) - } - }() + let imageViewSize = AVMakeRect(aspectRatio: image.size, insideRect: container.bounds.inset(by: container.safeAreaInsets)).size imageView.frame = CGRect(origin: .zero, size: imageViewSize) if imageView.image == nil { imageView.image = image } contentSize = imageViewSize - contentInset = imageContentInset centerScrollViewContents() - contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: setup image for container %s", ((#file as NSString).lastPathComponent), #line, #function, container.frame.debugDescription) } @@ -192,10 +183,7 @@ extension MediaPreviewImageView { frame.size = realImageSize imageView.frame = frame - let screenSize = self.frame.size - let offsetX = screenSize.width > realImageSize.width ? (screenSize.width - realImageSize.width) / 2 : 0 - let offsetY = screenSize.height > realImageSize.height ? (screenSize.height - realImageSize.height) / 2 : 0 - contentInset = UIEdgeInsets(top: offsetY, left: offsetX, bottom: offsetY, right: offsetX) + contentInset = self.safeAreaInsets // The scroll view has zoomed, so you need to re-center the contents let scrollViewSize = scrollViewVisibleSize diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index e28249312..127c4c0c0 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -46,10 +46,10 @@ extension MediaPreviewImageViewController { previewImageView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(previewImageView) NSLayoutConstraint.activate([ - previewImageView.frameLayoutGuide.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), - previewImageView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), - previewImageView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), - previewImageView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + previewImageView.frameLayoutGuide.topAnchor.constraint(equalTo: view.topAnchor), + previewImageView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor), + previewImageView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor), + previewImageView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) tapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.tapGestureRecognizerHandler(_:))) From 1c15b4c91cef257b8810cae2efeaac7ba52c24b0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 13:39:29 +0100 Subject: [PATCH 031/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 3113ada74..e80df74c5 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -2,39 +2,39 @@ "common": { "alerts": { "common": { - "please_try_again": "Please try again.", - "please_try_again_later": "Please try again later." + "please_try_again": "Будь ласка, спробуйте ще раз.", + "please_try_again_later": "Будь ласка, спробуйте пізніше." }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "Помилка реєстрації" }, "server_error": { - "title": "Server Error" + "title": "Помилка сервера" }, "vote_failure": { - "title": "Vote Failure", - "poll_ended": "The poll has ended" + "title": "Помилка голосування", + "poll_ended": "Опитування завершено" }, "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." + "title": "Видалити чернетку", + "message": "Підтвердьте, щоб відхилити створений вміст публікації." }, "publish_post_failure": { - "title": "Publish Failure", - "message": "Failed to publish the post.\nPlease check your internet connection.", + "title": "Помилка публікації", + "message": "Не вдалося опублікувати допис.\nПеревірте підключення до Інтернету.", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", - "more_than_one_video": "Cannot attach more than one video." + "video_attach_with_photo": "Не можна додати відео до допису з зображенням.", + "more_than_one_video": "Не можна додати більше ніж 1 відео." } }, "edit_profile_failure": { - "title": "Edit Profile Error", - "message": "Cannot edit profile. Please try again." + "title": "Помилка редагування профілю", + "message": "Не вдалося редагувати профіль. Будь ласка, спробуйте ще раз." }, "sign_out": { - "title": "Sign Out", - "message": "Are you sure you want to sign out?", - "confirm": "Sign Out" + "title": "Вийти", + "message": "Ви справді бажаєте вийти?", + "confirm": "Вийти" }, "block_domain": { "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", From b9179a43ecfba4c38442b7e9c3411fe6e1db693c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 13:39:30 +0100 Subject: [PATCH 032/733] New translations ios-infoPlist.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/ios-infoPlist.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/uk.lproj/ios-infoPlist.json index c6db73de0..bc953a077 100644 --- a/Localization/StringsConvertor/input/uk.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/uk.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" + "NSCameraUsageDescription": "Використовується, щоб зробити фотографію для статусу публікації", + "NSPhotoLibraryAddUsageDescription": "Використовується для збереження фото в бібліотеку", + "NewPostShortcutItemTitle": "Новий допис", + "SearchShortcutItemTitle": "Пошук" } From 43e66198e8a92757d99e7f8980e9a4c47169018e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 13:39:31 +0100 Subject: [PATCH 033/733] New translations Localizable.stringsdict (Ukrainian) --- .../StringsConvertor/input/uk.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict index 32e4cf9aa..c94d5d9c7 100644 --- a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict @@ -13,7 +13,7 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + 1 не прочитане сповіщення few %ld unread notification many From 42890981014a92d2c58ceb445b13ed3d479b6dec Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 13:39:32 +0100 Subject: [PATCH 034/733] New translations Intents.strings (Ukrainian) --- .../Intents/input/uk.lproj/Intents.strings | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.strings index 6877490ba..ecbc72785 100644 --- a/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.strings @@ -1,51 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Поділитись в Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Текстовий вміст"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Поділитись в Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Який зміст допису?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Помилка при надсиланні"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Причина помилки"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Надіслати пост із текстом"; -"RxSqsb" = "Post"; +"RxSqsb" = "Допис"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Опублікувати ${content} на Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Допис"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Видимість"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Видимість допису"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Знайдено ${count} варіантів, що задовольняють \"Публічні\"."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Знайдено ${count} варіантів, які відповідають \"Тільки для підписників\"."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, публічний"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, тільки підписники"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Поділитись в Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Публічно"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Тільки для підписників"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Помилка. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Допис успішно відправлено."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Вам дійсно потрібні \"Публічно\"?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Вам дійсно потрібні \"Тільки для підписників\"?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Допис успішно відправлено. "; From c4e44d50da4b6cdee1067470759bedbe077fa80c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 13:39:34 +0100 Subject: [PATCH 035/733] New translations Intents.stringsdict (Ukrainian) --- .../input/uk.lproj/Intents.stringsdict | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.stringsdict index a739f778f..ef8eb5d56 100644 --- a/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/uk.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + Знайдено %#@count_option@ відповідних '${content}. count_option NSStringFormatSpecTypeKey @@ -13,19 +13,19 @@ NSStringFormatValueTypeKey %ld one - 1 option + параметр few - %ld options + %ld параметри many - %ld options + %ld параметрів other - %ld options + %ld параметрів There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Знайдено %#@count_option@ відповідних '${visibility}. count_option NSStringFormatSpecTypeKey @@ -33,13 +33,13 @@ NSStringFormatValueTypeKey %ld one - 1 option + параметр few - %ld options + %ld параметри many - %ld options + %ld параметрів other - %ld options + %ld параметрів From 09e6873a4cca55d315e8cddf6aeaac6a35631172 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 14:34:54 +0100 Subject: [PATCH 036/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index e80df74c5..eadeebc3c 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -37,71 +37,71 @@ "confirm": "Вийти" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", - "block_entire_domain": "Block Domain" + "title": "Ви точно, точно впевнені, що хочете заблокувати весь домен %s? У більшості випадків для нормальної роботи краще заблокувати або приховати лише деяких користувачів. Ви не зможете бачити контент з цього домену у будь-яких стрічках або ваших сповіщеннях. Ваші підписники з цього домену будуть відписані від вас.", + "block_entire_domain": "Заблокувати домен" }, "save_photo_failure": { - "title": "Save Photo Failure", - "message": "Please enable the photo library access permission to save the photo." + "title": "Помилка збереження фото", + "message": "Будь ласка, увімкніть доступ до фотобібліотеки для збереження фотографій." }, "delete_post": { - "title": "Delete Post", - "message": "Are you sure you want to delete this post?" + "title": "Видалити допис", + "message": "Ви дійсно бажаєте видалити цей допис?" }, "clean_cache": { - "title": "Clean Cache", - "message": "Successfully cleaned %s cache." + "title": "Очистити кеш", + "message": "%s успішно очищено." } }, "controls": { "actions": { - "back": "Back", - "next": "Next", - "previous": "Previous", - "open": "Open", - "add": "Add", - "remove": "Remove", - "edit": "Edit", - "save": "Save", + "back": "Назад", + "next": "Далі", + "previous": "Попередній", + "open": "Відкрити", + "add": "Додати", + "remove": "Видалити", + "edit": "Редагувати", + "save": "Зберегти", "ok": "OK", - "done": "Done", - "confirm": "Confirm", - "continue": "Continue", - "compose": "Compose", - "cancel": "Cancel", - "discard": "Discard", - "try_again": "Try Again", - "take_photo": "Take Photo", - "save_photo": "Save Photo", - "copy_photo": "Copy Photo", - "sign_in": "Log in", - "sign_up": "Create account", - "see_more": "See More", - "preview": "Preview", - "share": "Share", - "share_user": "Share %s", - "share_post": "Share Post", - "open_in_safari": "Open in Safari", - "open_in_browser": "Open in Browser", - "find_people": "Find people to follow", - "manually_search": "Manually search instead", - "skip": "Skip", - "reply": "Reply", - "report_user": "Report %s", - "block_domain": "Block %s", - "unblock_domain": "Unblock %s", - "settings": "Settings", - "delete": "Delete" + "done": "Готово", + "confirm": "Підтвердити", + "continue": "Далі", + "compose": "Створити", + "cancel": "Скасувати", + "discard": "Відхилити", + "try_again": "Спробувати ще раз", + "take_photo": "Зробити фото", + "save_photo": "Зберегти фото", + "copy_photo": "Копіювати фото", + "sign_in": "Увійти", + "sign_up": "Створити обліковий запис", + "see_more": "Дивіться більше", + "preview": "Попередній перегляд", + "share": "Поділитись", + "share_user": "Поділитися %s", + "share_post": "Поділитися записом", + "open_in_safari": "Відкрити у Safari", + "open_in_browser": "Відкрити в браузері", + "find_people": "Знайти людей, аби підписатися", + "manually_search": "Натомість шукати вручну", + "skip": "Пропустити", + "reply": "Відповісти", + "report_user": "Поскаржитись на %s", + "block_domain": "Блокувати %s", + "unblock_domain": "Розблокувати %s", + "settings": "Налаштування", + "delete": "Видалити" }, "tabs": { - "home": "Home", - "search": "Search", - "notification": "Notification", - "profile": "Profile" + "home": "Головна", + "search": "Пошук", + "notification": "Сповіщення", + "profile": "Профіль" }, "keyboard": { "common": { - "switch_to_tab": "Switch to %s", + "switch_to_tab": "Перейти до користувача %s", "compose_new_post": "Compose New Post", "show_favorites": "Show Favorites", "open_settings": "Open Settings" From 344ea797e2c1f43c1d97f82996511902ec58b28f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 14:34:55 +0100 Subject: [PATCH 037/733] New translations Localizable.stringsdict (Ukrainian) --- .../input/uk.lproj/Localizable.stringsdict | 228 +++++++++--------- 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict index c94d5d9c7..21681e1b9 100644 --- a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict @@ -15,17 +15,17 @@ one 1 не прочитане сповіщення few - %ld unread notification + %ld не прочитаних сповіщень many - %ld unread notification + %ld не прочитаних сповіщень other - %ld unread notification + %ld не прочитаних сповіщень a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Перевищено ліміт вводу на %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -33,19 +33,19 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 символ few - %ld characters + %ld символи many - %ld characters + %ld символів other - %ld characters + %ld символів a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Залишається вхідний ліміт %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -53,19 +53,19 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 символ few - %ld characters + %ld символи many - %ld characters + %ld символів other - %ld characters + %ld символів a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ ліворуч character_count NSStringFormatSpecTypeKey @@ -73,13 +73,13 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 символ few - %ld characters + %ld символи many - %ld characters + %ld символів other - %ld characters + %ld символів plural.count.followed_by_and_mutual @@ -108,13 +108,13 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + Читають %1$@ та інші few - Followed by %1$@, and %ld mutuals + Читають %1$@, та %ld взаємних many - Followed by %1$@, and %ld mutuals + Читають %1$@, та %ld взаємних other - Followed by %1$@, and %ld mutuals + Читають %1$@, та %ld взаємних plural.count.metric_formatted.post @@ -128,13 +128,13 @@ NSStringFormatValueTypeKey ld one - post + допис few - posts + дописи many - posts + дописів other - posts + дописів plural.count.media @@ -148,13 +148,13 @@ NSStringFormatValueTypeKey ld one - 1 media + медіа few - %ld media + %ld медіа many - %ld media + %ld медіа other - %ld media + %ld медіа plural.count.post @@ -168,13 +168,13 @@ NSStringFormatValueTypeKey ld one - 1 post + 1 пост few - %ld posts + %ld пости many - %ld posts + %ld постів other - %ld posts + %ld постів plural.count.favorite @@ -188,13 +188,13 @@ NSStringFormatValueTypeKey ld one - 1 favorite + 1 улюблене few - %ld favorites + %ld улюблених many - %ld favorites + %ld улюблених other - %ld favorites + %ld улюблених plural.count.reblog @@ -208,13 +208,13 @@ NSStringFormatValueTypeKey ld one - 1 reblog + 1 репост few - %ld reblogs + %ld репости many - %ld reblogs + %ld репостів other - %ld reblogs + %ld репостів plural.count.reply @@ -228,13 +228,13 @@ NSStringFormatValueTypeKey ld one - 1 reply + 1 відповідь few - %ld replies + %ld відповіді many - %ld replies + %ld відповідей other - %ld replies + %ld відповідей plural.count.vote @@ -248,13 +248,13 @@ NSStringFormatValueTypeKey ld one - 1 vote + 1 голос few - %ld votes + %ld голоси many - %ld votes + %ld голосів other - %ld votes + %ld голосів plural.count.voter @@ -268,13 +268,13 @@ NSStringFormatValueTypeKey ld one - 1 voter + 1 учасник голосування few - %ld voters + %ld учасники голосування many - %ld voters + %ld учасників голосування other - %ld voters + %ld учасників голосування plural.people_talking @@ -288,13 +288,13 @@ NSStringFormatValueTypeKey ld one - 1 people talking + 1 людина говорить few - %ld people talking + %ld людей говорять many - %ld people talking + %ld людей говорять other - %ld people talking + %ld людей говорять plural.count.following @@ -308,13 +308,13 @@ NSStringFormatValueTypeKey ld one - 1 following + підписаний few - %ld following + Підписаний на %ld many - %ld following + Підписаний на %ld other - %ld following + Підписаний на %ld plural.count.follower @@ -328,13 +328,13 @@ NSStringFormatValueTypeKey ld one - 1 follower + 1 підписник few - %ld followers + %ld підписників many - %ld followers + %ld підписників other - %ld followers + %ld підписників date.year.left @@ -348,13 +348,13 @@ NSStringFormatValueTypeKey ld one - 1 year left + залишився 1 рік few - %ld years left + %ld років залишилося many - %ld years left + %ld років залишилося other - %ld years left + %ld років залишилося date.month.left @@ -368,13 +368,13 @@ NSStringFormatValueTypeKey ld one - 1 months left + 1 місяць залишився few - %ld months left + %ld місяців залишилося many - %ld months left + %ld місяців залишилося other - %ld months left + %ld місяців залишилося date.day.left @@ -388,13 +388,13 @@ NSStringFormatValueTypeKey ld one - 1 day left + Лишився 1 день few - %ld days left + %ld днів залишилося many - %ld days left + %ld днів залишилося other - %ld days left + %ld днів залишилося date.hour.left @@ -408,13 +408,13 @@ NSStringFormatValueTypeKey ld one - 1 hour left + Залишилася 1 година few - %ld hours left + %ld годин залишилося many - %ld hours left + %ld годин залишилося other - %ld hours left + %ld годин залишилося date.minute.left @@ -428,13 +428,13 @@ NSStringFormatValueTypeKey ld one - 1 minute left + Залишилась одна хвилина few - %ld minutes left + %ld хвилин залишилося many - %ld minutes left + %ld хвилин залишилося other - %ld minutes left + %ld хвилин залишилося date.second.left @@ -448,13 +448,13 @@ NSStringFormatValueTypeKey ld one - 1 second left + Залишилась одна секунда few - %ld seconds left + %ld секунд залишилося many - %ld seconds left + %ld секунд залишилося other - %ld seconds left + %ld секунд залишилося date.year.ago.abbr @@ -468,13 +468,13 @@ NSStringFormatValueTypeKey ld one - 1y ago + 1 рік тому few - %ldy ago + %ld роки тому many - %ldy ago + %ld років тому other - %ldy ago + %ld років тому date.month.ago.abbr @@ -488,13 +488,13 @@ NSStringFormatValueTypeKey ld one - 1M ago + 1 місяць тому few - %ldM ago + %ld місяці тому many - %ldM ago + %ld місяців тому other - %ldM ago + %ld Місяців тому date.day.ago.abbr @@ -508,13 +508,13 @@ NSStringFormatValueTypeKey ld one - 1d ago + 1 день тому few - %ldd ago + %ld дня тому many - %ldd ago + %ld днів тому other - %ldd ago + %ld днів тому date.hour.ago.abbr @@ -528,13 +528,13 @@ NSStringFormatValueTypeKey ld one - 1h ago + 1 годину тому few - %ldh ago + %ld години тому many - %ldh ago + %ld годин тому other - %ldh ago + %ld годин тому date.minute.ago.abbr @@ -548,13 +548,13 @@ NSStringFormatValueTypeKey ld one - 1m ago + 1 хвилину тому few - %ldm ago + %ld хвилини тому many - %ldm ago + %ld хвилин тому other - %ldm ago + %ld хвилин тому date.second.ago.abbr @@ -568,13 +568,13 @@ NSStringFormatValueTypeKey ld one - 1s ago + 1 секунду тому few - %lds ago + %ld секунди тому many - %lds ago + %ld секунд тому other - %lds ago + %ld секунд тому From 0f96787d687e40064b744117e7f9629741343d85 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 16:19:07 +0100 Subject: [PATCH 038/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index eadeebc3c..aafc5640f 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -102,89 +102,89 @@ "keyboard": { "common": { "switch_to_tab": "Перейти до користувача %s", - "compose_new_post": "Compose New Post", - "show_favorites": "Show Favorites", - "open_settings": "Open Settings" + "compose_new_post": "Написати новий допис", + "show_favorites": "Показати вибрані", + "open_settings": "Відкрити параметри" }, "timeline": { - "previous_status": "Previous Post", - "next_status": "Next Post", - "open_status": "Open Post", - "open_author_profile": "Open Author's Profile", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", - "toggle_reblog": "Toggle Reblog on Post", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", - "preview_image": "Preview Image" + "previous_status": "Попередній допис", + "next_status": "Новий допис", + "open_status": "Відкрити допис", + "open_author_profile": "Відкрити профіль автора", + "open_reblogger_profile": "Відкрити профіль реблогера", + "reply_status": "Відповісти на допис", + "toggle_reblog": "Додати/прибрати Реблог", + "toggle_favorite": "Додати/прибрати з Обраного", + "toggle_content_warning": "Додати/прибрати попередження про вміст для дорослих", + "preview_image": "Попередній перегляд" }, "segmented_control": { - "previous_section": "Previous Section", - "next_section": "Next Section" + "previous_section": "Попередній розділ", + "next_section": "Наступний розділ" } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", - "show_post": "Show Post", - "show_user_profile": "Show user profile", - "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", + "user_reblogged": "%s Зробив репост", + "user_replied_to": "Відповів %s", + "show_post": "Показати дописи", + "show_user_profile": "Показати профіль користувача", + "content_warning": "Попередження про вміст", + "sensitive_content": "Контент 18+", + "media_content_warning": "Натисніть будь-де, щоб показати більше", + "tap_to_reveal": "Натисніть, щоб відобразити", "poll": { - "vote": "Vote", - "closed": "Closed" + "vote": "Проголосувати", + "closed": "Зачинено" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Посилання: %s", + "hashtag": "Гештег: %s", + "mention": "Показати профіль: %s", + "email": "Електронна адреса: %s" }, "actions": { - "reply": "Reply", - "reblog": "Reblog", - "unreblog": "Undo reblog", - "favorite": "Favorite", - "unfavorite": "Unfavorite", - "menu": "Menu", - "hide": "Hide", - "show_image": "Show image", - "show_gif": "Show GIF", - "show_video_player": "Show video player", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "reply": "Відповісти", + "reblog": "Репост", + "unreblog": "Скасувати репост", + "favorite": "Улюблене", + "unfavorite": "Вилучити з улюбленого", + "menu": "Меню", + "hide": "Сховати", + "show_image": "Показати зображення", + "show_gif": "Показати GIF", + "show_video_player": "Показати відеоплеєр", + "tap_then_hold_to_show_menu": "Натисніть та утримуйте, щоб показати меню" }, "tag": { - "url": "URL", - "mention": "Mention", - "link": "Link", - "hashtag": "Hashtag", - "email": "Email", - "emoji": "Emoji" + "url": "Адреса URL", + "mention": "Згадати", + "link": "Посилання", + "hashtag": "Гештег", + "email": "Електронна пошта", + "emoji": "Емодзі" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "Хто завгодно може бачити цей допис, але його не буде відображено у публічній стрічці.", + "private": "Лише їхні підписники можуть бачити цю публікацію.", + "private_from_me": "Тільки мої підписники можуть бачити цю публікацію.", + "direct": "Тільки згаданий користувач може бачити цю публікацію." } }, "friendship": { - "follow": "Follow", - "following": "Following", - "request": "Request", - "pending": "Pending", - "block": "Block", - "block_user": "Block %s", - "block_domain": "Block %s", - "unblock": "Unblock", - "unblock_user": "Unblock %s", - "blocked": "Blocked", - "mute": "Mute", - "mute_user": "Mute %s", - "unmute": "Unmute", - "unmute_user": "Unmute %s", + "follow": "Підписатися", + "following": "Підписаний", + "request": "Запит", + "pending": "Очікується", + "block": "Заблокувати", + "block_user": "Блокувати %s", + "block_domain": "Блокувати %s", + "unblock": "Розблокувати", + "unblock_user": "Розблокувати %s", + "blocked": "Заблоковано", + "mute": "Заглушити", + "mute_user": "Заглушити %s", + "unmute": "Сповіщати", + "unmute_user": "Сповіщати %s", "muted": "Muted", "edit_info": "Edit Info", "show_reblogs": "Show Reblogs", @@ -198,14 +198,14 @@ "loader": { "load_missing_posts": "Load missing posts", "loading_missing_posts": "Loading missing posts...", - "show_more_replies": "Show more replies" + "show_more_replies": "Показати більше відповідей" }, "header": { - "no_status_found": "No Post Found", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "no_status_found": "Публікацій не знайдено", + "blocking_warning": "Ви не можете переглянути профіль цього користувача, поки ви не розблокуєте їх.\nВаш профіль виглядає так.", + "user_blocking_warning": "Ви не можете переглядати профіль %s, поки ви не розблокуєте їх.\nВони бачать ваш профіль так.", + "blocked_warning": "Ви не можете переглянути профіль цього користувача, поки вони не розблокують вас.", + "user_blocked_warning": "Ви не можете переглянути профіль %s, поки він не розблокує вас.", "suspended_warning": "This user has been suspended.", "user_suspended_warning": "%s’s account has been suspended." } @@ -282,60 +282,60 @@ "password": { "placeholder": "password", "require": "Your password needs at least:", - "character_limit": "8 characters", + "character_limit": "8 символів", "accessibility": { - "checked": "checked", - "unchecked": "unchecked" + "checked": "встановлено", + "unchecked": "знято позначку" }, - "hint": "Your password needs at least eight characters" + "hint": "Ваш пароль повинен містити принаймні вісім символів" }, "invite": { - "registration_user_invite_request": "Why do you want to join?" + "registration_user_invite_request": "Чому ви хочете приєднатися?" } }, "error": { "item": { - "username": "Username", - "email": "Email", - "password": "Password", - "agreement": "Agreement", - "locale": "Locale", - "reason": "Reason" + "username": "Ім'я користувача", + "email": "Електронна пошта", + "password": "Пароль", + "agreement": "Угода", + "locale": "Локаль", + "reason": "Підстава" }, "reason": { - "blocked": "%s contains a disallowed email provider", - "unreachable": "%s does not seem to exist", - "taken": "%s is already in use", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", - "blank": "%s is required", - "invalid": "%s is invalid", - "too_long": "%s is too long", - "too_short": "%s is too short", - "inclusion": "%s is not a supported value" + "blocked": "%s містить заборонених провайдерів email", + "unreachable": "%s здається, не існує", + "taken": "%s вже використовується", + "reserved": "%s є зарезервованим ключовим словом", + "accepted": "%s має бути прийнято", + "blank": "%s необхідно", + "invalid": "%s є недійсним", + "too_long": "%s занадто довгий", + "too_short": "%s є закоротким", + "inclusion": "%s не є підтримуваним значенням" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", - "password_too_short": "Password is too short (must be at least 8 characters)" + "username_invalid": "Ім'я користувача повинно містити лише літери, цифрові символи та знак підкреслення", + "username_too_long": "Ім'я користувача занадто довге (не може бути більше 30 символів)", + "email_invalid": "Це не дійсна адреса електронної пошти", + "password_too_short": "Пароль закороткий (має містити мінімум 8 символів)" } } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "title": "Деякі основні правила.", + "subtitle": "Ці призначені для модераторів - %s.", + "prompt": "Продовжуючи, ви піддаєтеся умовам надання послуг та політики конфіденційності для хвороби %s.", + "terms_of_service": "умови використання", + "privacy_policy": "політика конфіденційності", "button": { - "confirm": "I Agree" + "confirm": "Я погоджуюся" } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "title": "Остання річ.", + "subtitle": "Натисніть на посилання, яке ми надіслали на вашу пошту, щоб підтвердити свій обліковий запис.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Натисніть на посилання, яке ми надіслали на вашу пошту, щоб підтвердити свій обліковий запис", "button": { "open_email_app": "Open Email App", "resend": "Resend" From 590e91d723e8f1bb4a0acef454abeda7f21c79fe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 17:23:56 +0100 Subject: [PATCH 039/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index aafc5640f..9158e2ad7 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -337,31 +337,31 @@ "subtitle": "Натисніть на посилання, яке ми надіслали на вашу пошту, щоб підтвердити свій обліковий запис.", "tap_the_link_we_emailed_to_you_to_verify_your_account": "Натисніть на посилання, яке ми надіслали на вашу пошту, щоб підтвердити свій обліковий запис", "button": { - "open_email_app": "Open Email App", - "resend": "Resend" + "open_email_app": "Відкрити додаток Електронної пошти", + "resend": "Повторно надіслати" }, "dont_receive_email": { - "title": "Check your email", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "title": "Перевірте свою електронну пошту", + "description": "Перевірте правильність адреси електронної пошти, а також теку зі спамом, якщо ви ще не зробили цього.", + "resend_email": "Повторно надіслати лист" }, "open_email_app": { - "title": "Check your inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", - "mail": "Mail", - "open_email_client": "Open Email Client" + "title": "Перевірте вашу поштову скриньку.", + "description": "Ми щойно надіслали вам електронного листа. Перевірте вашу спам теку, якщо ви не зробили цього.", + "mail": "Пошта", + "open_email_client": "Відкрити поштового клієнта" } }, "home_timeline": { - "title": "Home", + "title": "Головна", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "В автономному режимі", + "new_posts": "До нових дописів", + "published": "Опубліковано!", + "Publishing": "Допис публікується...", "accessibility": { - "logo_label": "Logo Button", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_label": "Кнопка Логотипу", + "logo_hint": "Торкніться для прокручування вгору і натисніть ще раз на попереднє розташування" } } }, @@ -435,99 +435,99 @@ "publish_post": "Publish Post", "toggle_poll": "Toggle Poll", "toggle_content_warning": "Toggle Content Warning", - "append_attachment_entry": "Add Attachment - %s", - "select_visibility_entry": "Select Visibility - %s" + "append_attachment_entry": "Додати вкладення - %s", + "select_visibility_entry": "Оберіть видимість - %s" } }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Підписаний(-на) на вас" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "posts": "дописів", + "following": "підписаний", + "followers": "підписників" }, "fields": { - "add_row": "Add Row", + "add_row": "Додати рядок", "placeholder": { - "label": "Label", - "content": "Content" + "label": "Позначка", + "content": "Зміст" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Перевірено %s", + "long": "Права власності на це посилання були перевірені %s" } }, "segmented_control": { - "posts": "Posts", - "replies": "Replies", - "posts_and_replies": "Posts and Replies", - "media": "Media", - "about": "About" + "posts": "Дописи", + "replies": "Відповіді", + "posts_and_replies": "Дописи й відповіді", + "media": "Медіа", + "about": "Про застосунок" }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Заглушити обліковий запис", + "message": "Підтвердити заглушення %s" }, "confirm_unmute_user": { - "title": "Unmute Account", - "message": "Confirm to unmute %s" + "title": "Розглушити обліковий запис", + "message": "Підтвердить розглушення %s" }, "confirm_block_user": { - "title": "Block Account", - "message": "Confirm to block %s" + "title": "Заблокувати обліковий запис", + "message": "Підтвердити блокування %s" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Розблокувати обліковий запис", + "message": "Підтвердити розблокування %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Показати реблоги", + "message": "Підтвердити показ реблогів" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Сховати реблоги", + "message": "Підтвердити, щоб приховати реблоги" } }, "accessibility": { - "show_avatar_image": "Show avatar image", - "edit_avatar_image": "Edit avatar image", - "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "show_avatar_image": "Показати аватар користувача", + "edit_avatar_image": "Редагувати аватар", + "show_banner_image": "Показати зображення банера", + "double_tap_to_open_the_list": "Натисніть двічі, щоб відчинити список" } }, "follower": { - "title": "follower", - "footer": "Followers from other servers are not displayed." + "title": "підписник", + "footer": "Підписники з інших серверів не відображаються." }, "following": { - "title": "following", - "footer": "Follows from other servers are not displayed." + "title": "підписаний", + "footer": "Підписки з інших серверів не відображаються." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Підписники, яких ви знаєте", + "followed_by_names": "Має серед підписників %s" }, "favorited_by": { - "title": "Favorited By" + "title": "Є в обраних у" }, "reblogged_by": { - "title": "Reblogged By" + "title": "Репостнуто" }, "search": { - "title": "Search", + "title": "Пошук", "search_bar": { - "placeholder": "Search hashtags and users", - "cancel": "Cancel" + "placeholder": "Пошук за гештегами та користувачами", + "cancel": "Скасувати" }, "recommend": { - "button_text": "See All", + "button_text": "Переглянути всі", "hash_tag": { - "title": "Trending on Mastodon", - "description": "Hashtags that are getting quite a bit of attention", + "title": "У Трендах на Мастодоні", + "description": "Гештеги, що привертають увагу", "people_talking": "%s people are talking" }, "accounts": { From d2f683ea844bb42b224caf7da3813b631853d4fc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 20:19:07 +0100 Subject: [PATCH 040/733] New translations app.json (Turkish) --- .../StringsConvertor/input/tr.lproj/app.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 37325cf05..3507d1f5c 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -74,8 +74,8 @@ "take_photo": "Fotoğraf Çek", "save_photo": "Fotoğrafı Kaydet", "copy_photo": "Fotoğrafı Kopyala", - "sign_in": "Log in", - "sign_up": "Create account", + "sign_in": "Giriş Yap", + "sign_up": "Hesap oluştur", "see_more": "Daha Fazla Gör", "preview": "Önizleme", "share": "Paylaş", @@ -137,10 +137,10 @@ "closed": "Kapandı" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Bağlantı: %s", + "hashtag": "Etiket: %s", + "mention": "Profili Göster: %s", + "email": "E-posta adresi: %s" }, "actions": { "reply": "Yanıtla", @@ -219,7 +219,7 @@ "log_in": "Oturum Aç" }, "login": { - "title": "Welcome back", + "title": "Tekrar hoş geldin", "subtitle": "Log you in on the server you created your account on.", "server_search_field": { "placeholder": "Enter URL or search for your server" @@ -388,11 +388,11 @@ "attachment_broken": "Bu %s bozuk ve Mastodon'a\nyüklenemiyor.", "description_photo": "Görme engelliler için fotoğrafı tarif edin...", "description_video": "Görme engelliler için videoyu tarif edin...", - "load_failed": "Load Failed", + "load_failed": "Yükleme Başarısız", "upload_failed": "Upload Failed", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", + "compressing_state": "Sıkıştırılıyor...", "server_processing_state": "Server Processing..." }, "poll": { @@ -581,10 +581,10 @@ "show_mentions": "Bahsetmeleri Göster" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Kabul Et", + "accepted": "Kabul Edildi", + "reject": "Reddet", + "rejected": "Reddedildi" } }, "thread": { @@ -669,9 +669,9 @@ "i_dont_like_it": "Beğenmedim", "it_is_not_something_you_want_to_see": "Görmek isteyeceğim bir şey değil", "its_spam": "Spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "malicious_links_fake_engagement_or_repetetive_replies": "Kötü niyetli bağlantılar, sahte etkileşim veya tekrarlayan yanıtlar", "it_violates_server_rules": "Sunucu kurallarını ihlal ediyor", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "you_are_aware_that_it_breaks_specific_rules": "Belirli kuralları ihlal ettiğinin farkındasınız", "its_something_else": "Başka bir şey", "the_issue_does_not_fit_into_other_categories": "Sorun bunlardan biri değil" }, @@ -692,9 +692,9 @@ }, "step_final": { "dont_want_to_see_this": "Bunu görmek istemiyor musunuz?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Mastodon'da beğenmediğiniz bir şey gördüğünüzde, o kişiyi deneyiminizden çıkarabilirsiniz.", "unfollow": "Takibi bırak", - "unfollowed": "Unfollowed", + "unfollowed": "Takipten çıkıldı", "unfollow_user": "Takipten çık %s", "mute_user": "Sustur %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", @@ -721,7 +721,7 @@ "accessibility_hint": "Bu yardımı kapatmak için çift tıklayın" }, "bookmark": { - "title": "Bookmarks" + "title": "Yer İmleri" } } } From e7f2a9c03ffbd1ed259729828dec17db9df2d82e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 20:19:09 +0100 Subject: [PATCH 041/733] New translations Localizable.stringsdict (Turkish) --- .../input/tr.lproj/Localizable.stringsdict | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict index 6ef7f4c75..13552b607 100644 --- a/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ kaldı character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 karakter other - %ld characters + %ld karakter plural.count.followed_by_and_mutual @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + %1$@ ve bir ortak kişi tarafından takip edildi other - Followed by %1$@, and %ld mutuals + %1$@ ve %ld ortak kişi tarafından takip edildi plural.count.metric_formatted.post @@ -120,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 media + 1 medya other - %ld media + %ld medya plural.count.post From 64fa222b3ed13099029fb0985fee259eed033a76 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Nov 2022 23:54:18 +0100 Subject: [PATCH 042/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 9158e2ad7..a1eaf74f4 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -185,8 +185,8 @@ "mute_user": "Заглушити %s", "unmute": "Сповіщати", "unmute_user": "Сповіщати %s", - "muted": "Muted", - "edit_info": "Edit Info", + "muted": "Зам'ютити", + "edit_info": "Редагувати інформацію", "show_reblogs": "Show Reblogs", "hide_reblogs": "Hide Reblogs" }, From 3cd24e3bbd7a81aadb2c848a4a38578ae7bf8265 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 00:57:04 +0100 Subject: [PATCH 043/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index a1eaf74f4..1698eea23 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -187,17 +187,17 @@ "unmute_user": "Сповіщати %s", "muted": "Зам'ютити", "edit_info": "Редагувати інформацію", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "Показати реблоги", + "hide_reblogs": "Сховати реблоги" }, "timeline": { - "filtered": "Filtered", + "filtered": "Відфільтровано", "timestamp": { - "now": "Now" + "now": "Щойно" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", + "load_missing_posts": "Завантажити пропущені дописи", + "loading_missing_posts": "Завантаження пропущених дописів...", "show_more_replies": "Показати більше відповідей" }, "header": { @@ -206,82 +206,82 @@ "user_blocking_warning": "Ви не можете переглядати профіль %s, поки ви не розблокуєте їх.\nВони бачать ваш профіль так.", "blocked_warning": "Ви не можете переглянути профіль цього користувача, поки вони не розблокують вас.", "user_blocked_warning": "Ви не можете переглянути профіль %s, поки він не розблокує вас.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "suspended_warning": "Цього користувача було заблоковано.", + "user_suspended_warning": "Обліковий запис %s заблоковано." } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", - "log_in": "Log In" + "slogan": "Соціальна мережа під вашим контролем.", + "get_started": "Почати", + "log_in": "Увійти" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "З поверненням", + "subtitle": "Увійдіть на сервері, де ви створили свій обліковий запис.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Введіть URL-адресу або адресу сервера" } }, "server_picker": { - "title": "Mastodon is made of users in different servers.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "title": "Mastodon складається з користувачів на різних серверах.", + "subtitle": "Оберіть сервер згідно з вашим регіоном, інтересами чи цілями. Ви можете спілкуватися з будь-ким на Mastodon, незалежно від обраних серверів.", "button": { "category": { - "all": "All", - "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", - "food": "food", - "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", - "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "all": "Всі", + "all_accessiblity_description": "Категорія: Усі", + "academia": "академія", + "activism": "активізм", + "food": "їжа", + "furry": "фурі", + "games": "ігри", + "general": "загальне", + "journalism": "журналістика", + "lgbt": "лгбт", + "regional": "регіональний", + "art": "мистецтво", + "music": "музика", + "tech": "технології" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "Згорнути", + "see_more": "Показати більше" }, "label": { - "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "language": "МОВА", + "users": "КОРИСТУВАЧІ", + "category": "КАТЕГОРІЯ" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Знайти спільноти, або ввести URL" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "finding_servers": "Пошук доступних серверів...", + "bad_network": "Сталася помилка під час завантаження даних. Перевірте підключення до Інтернету.", + "no_results": "Жодних результатів" } }, "register": { - "title": "Let’s get you set up on %s", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "title": "Налаштуймо Вас на %s", + "lets_get_you_set_up_on_domain": "Налаштуймо Вас на %s", "input": { "avatar": { - "delete": "Delete" + "delete": "Видалити" }, "username": { - "placeholder": "username", - "duplicate_prompt": "This username is taken." + "placeholder": "ім'я користувача", + "duplicate_prompt": "Це ім'я користувача вже зайняте." }, "display_name": { - "placeholder": "display name" + "placeholder": "видиме ім'я" }, "email": { - "placeholder": "email" + "placeholder": "електронна пошта" }, "password": { - "placeholder": "password", - "require": "Your password needs at least:", + "placeholder": "пароль", + "require": "Ваш пароль повинен містити як мінімум:", "character_limit": "8 символів", "accessibility": { "checked": "встановлено", @@ -528,56 +528,56 @@ "hash_tag": { "title": "У Трендах на Мастодоні", "description": "Гештеги, що привертають увагу", - "people_talking": "%s people are talking" + "people_talking": "%s людей говорять" }, "accounts": { - "title": "Accounts you might like", - "description": "You may like to follow these accounts", - "follow": "Follow" + "title": "Акавнти, що можуть вам сподобатися", + "description": "Ви можете зацікавитися цими обліковими записами", + "follow": "Підписатися" } }, "searching": { "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" + "all": "Всі", + "people": "Громада", + "hashtags": "Гештеги", + "posts": "Дописи" }, "empty_state": { - "no_results": "No results" + "no_results": "Жодних результатів" }, - "recent_search": "Recent searches", - "clear": "Clear" + "recent_search": "Нещодавні запити", + "clear": "Очистити" } }, "discovery": { "tabs": { - "posts": "Posts", - "hashtags": "Hashtags", - "news": "News", - "community": "Community", - "for_you": "For You" + "posts": "Дописи", + "hashtags": "Гештеги", + "news": "Новини", + "community": "Спільнота", + "for_you": "Для Вас" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Ось найбільш популярні дописи серед вашого серверу Mastodon." }, "favorite": { - "title": "Your Favorites" + "title": "Ваші Вподобання" }, "notification": { "title": { - "Everything": "Everything", - "Mentions": "Mentions" + "Everything": "Все", + "Mentions": "Згадки" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", - "reblogged_your_post": "reblogged your post", - "mentioned_you": "mentioned you", - "request_to_follow_you": "request to follow you", - "poll_has_ended": "poll has ended" + "followed_you": "підписався(-лась) на вас", + "favorited_your_post": "вподобав(-ла) ваш допис", + "reblogged_your_post": "поширив(-ла) ваш допис", + "mentioned_you": "згадав(-ла) вас", + "request_to_follow_you": "запит на підписку", + "poll_has_ended": "опитування завершено" }, "keyobard": { - "show_everything": "Show Everything", + "show_everything": "Показати все", "show_mentions": "Show Mentions" }, "follow_request": { From 7c1dbc6130fd1a1978b1b5cd81e94c51f077a60f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 02:13:56 +0100 Subject: [PATCH 044/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 1698eea23..b2524ed5b 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -578,17 +578,17 @@ }, "keyobard": { "show_everything": "Показати все", - "show_mentions": "Show Mentions" + "show_mentions": "Показати Згадки" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Прийняти", + "accepted": "Прийнято", + "reject": "відхилити", + "rejected": "Відхилено" } }, "thread": { - "back_title": "Post", + "back_title": "Допис", "title": "Post from %s" }, "settings": { From fb67ee1c1e38a6f9f68780e4c7c830f2094e2b79 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 12:45:44 +0100 Subject: [PATCH 045/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index b2524ed5b..cc102f50b 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -366,75 +366,75 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Знайти людей, аби підписатися", + "follow_explain": "Коли ви підпишетесь на когось, ви побачите його дописи у своїй домашній стрічці." }, "compose": { "title": { - "new_post": "New Post", - "new_reply": "New Reply" + "new_post": "Новий допис", + "new_reply": "Нова відповідь" }, "media_selection": { - "camera": "Take Photo", - "photo_library": "Photo Library", - "browse": "Browse" + "camera": "Зробити фото", + "photo_library": "Галерея", + "browse": "Огляд" }, - "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", + "content_input_placeholder": "Що у Вас на думці", + "compose_action": "Опублікувати", + "replying_to_user": "відповідь на: %s", "attachment": { - "photo": "photo", - "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "photo": "фото", + "video": "відео", + "attachment_broken": "Цей %s пошкоджений і не може бути\nзавантажений в Mastodon.", + "description_photo": "Опишіть фото для людей з вадами зору...", + "description_video": "Опишіть відео для людей з вадами зору...", + "load_failed": "Не вдалося завантажити", + "upload_failed": "Не вдалося завантажити", + "can_not_recognize_this_media_attachment": "Неможливо розпізнати цей медіафайл", + "attachment_too_large": "Вкладення завелике", + "compressing_state": "Стиснення...", + "server_processing_state": "Обробка сервера..." }, "poll": { - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", - "three_days": "3 Days", - "seven_days": "7 Days", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "duration_time": "Тривалість: %s", + "thirty_minutes": "30 хвилин", + "one_hour": "1 Година", + "six_hours": "6 Годин", + "one_day": "1 День", + "three_days": "3 Дні", + "seven_days": "7 Днів", + "option_number": "Параметр %ld", + "the_poll_is_invalid": "Неприпустимий варіант опитування", + "the_poll_has_empty_option": "В опитуванні є порожній варіант" }, "content_warning": { - "placeholder": "Write an accurate warning here..." + "placeholder": "Напишіть своє попередження тут..." }, "visibility": { - "public": "Public", - "unlisted": "Unlisted", - "private": "Followers only", - "direct": "Only people I mention" + "public": "Публічно", + "unlisted": "Приховувати зі стрічок", + "private": "Тільки для підписників", + "direct": "Тільки людям, яких я згадав" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Пробіл, щоб додати" }, "accessibility": { - "append_attachment": "Add Attachment", - "append_poll": "Add Poll", - "remove_poll": "Remove Poll", - "custom_emoji_picker": "Custom Emoji Picker", - "enable_content_warning": "Enable Content Warning", - "disable_content_warning": "Disable Content Warning", - "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "append_attachment": "Додати вкладення", + "append_poll": "Додати опитування", + "remove_poll": "Видалити опитування", + "custom_emoji_picker": "Вибір власних емодзі", + "enable_content_warning": "Увімкнути попередження про контент", + "disable_content_warning": "Вимкнути попередження про контент", + "post_visibility_menu": "Меню видимості поста", + "post_options": "Параметри повідомлення", + "posting_as": "Опублікувати як %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", - "toggle_poll": "Toggle Poll", - "toggle_content_warning": "Toggle Content Warning", + "discard_post": "Відхилити допис", + "publish_post": "Опублікувати повідомлення", + "toggle_poll": "Відкрити або закрити опитування", + "toggle_content_warning": "Попередження про вміст", "append_attachment_entry": "Додати вкладення - %s", "select_visibility_entry": "Оберіть видимість - %s" } From 105d25cde1c78161aa01e1655cb0199ffeb246e0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 15:18:47 +0100 Subject: [PATCH 046/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 4f2050792..f72e178bb 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -338,7 +338,7 @@ "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "Buka Aplikasi Surel", - "resend": "Resend" + "resend": "Kirim ulang" }, "dont_receive_email": { "title": "Periksa surel Anda", @@ -360,13 +360,13 @@ "published": "Dipublikasikan!", "Publishing": "Mempublikasikan postingan...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Tombol Logo", "logo_hint": "Tap to scroll to top and tap again to previous location" } } }, "suggestion_account": { - "title": "Find People to Follow", + "title": "Temukan Orang untuk Diikuti", "follow_explain": "Ketika Anda mengikuti seseorang, Anda akan melihat postingan mereka di beranda Anda." }, "compose": { @@ -376,7 +376,7 @@ }, "media_selection": { "camera": "Ambil Foto", - "photo_library": "Photo Library", + "photo_library": "Galeri Foto", "browse": "Telusuri" }, "content_input_placeholder": "Ketik atau tempel apa yang Anda pada pikiran Anda", @@ -441,7 +441,7 @@ }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Mengikutimu" }, "dashboard": { "posts": "postingan", @@ -464,24 +464,24 @@ "replies": "Balasan", "posts_and_replies": "Posts and Replies", "media": "Media", - "about": "About" + "about": "Tentang" }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Bisukan Akun", + "message": "Konfirmasi untuk bisukan %s" }, "confirm_unmute_user": { "title": "Berhenti Membisukan Akun", "message": "Confirm to unmute %s" }, "confirm_block_user": { - "title": "Block Account", - "message": "Confirm to block %s" + "title": "Blokir Akun", + "message": "Konfirmasi memblokir %s" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Buka Blokir Akun", + "message": "Konfirmasi membuka blokir %s" }, "confirm_show_reblogs": { "title": "Show Reblogs", @@ -493,18 +493,18 @@ } }, "accessibility": { - "show_avatar_image": "Show avatar image", + "show_avatar_image": "Tampilkan gambar avatar", "edit_avatar_image": "Edit avatar image", "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "double_tap_to_open_the_list": "Ketuk ganda untuk membuka daftar" } }, "follower": { - "title": "follower", + "title": "pengikut", "footer": "Followers from other servers are not displayed." }, "following": { - "title": "following", + "title": "mengikuti", "footer": "Follows from other servers are not displayed." }, "familiarFollowers": { @@ -569,8 +569,8 @@ "Mentions": "Sebutan" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", + "followed_you": "mengikutimu", + "favorited_your_post": "menyukai postinganmu", "reblogged_your_post": "reblogged your post", "mentioned_you": "mentioned you", "request_to_follow_you": "request to follow you", From 25e1223f633f7e286c0b9dd25319621e45155a12 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:22 +0100 Subject: [PATCH 047/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 178 +++++++++--------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index cc102f50b..987f65cf4 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -589,139 +589,139 @@ }, "thread": { "back_title": "Допис", - "title": "Post from %s" + "title": "Публікація від %s" }, "settings": { - "title": "Settings", + "title": "Налаштування", "section": { "appearance": { - "title": "Appearance", - "automatic": "Automatic", - "light": "Always Light", - "dark": "Always Dark" + "title": "Оформлення", + "automatic": "Автоматичне", + "light": "Завжди світле", + "dark": "Завжди темне" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "Зовнішній вид", + "use_system": "Використати системний", + "really_dark": "Дуже темний", + "sorta_dark": "Трішкий темний", + "light": "Світлий" }, "notifications": { - "title": "Notifications", - "favorites": "Favorites my post", - "follows": "Follows me", - "boosts": "Reblogs my post", - "mentions": "Mentions me", + "title": "Сповіщення", + "favorites": "Вподобав ваш допис", + "follows": "Підписався на мене", + "boosts": "Реблог мого посту", + "mentions": "Згадує мене", "trigger": { - "anyone": "anyone", - "follower": "a follower", - "follow": "anyone I follow", - "noone": "no one", - "title": "Notify me when" + "anyone": "усі", + "follower": "підписник", + "follow": "хтось, за ким я слідкую", + "noone": "ніхто", + "title": "Повідомити мене, коли" } }, "preference": { - "title": "Preferences", - "true_black_dark_mode": "True black dark mode", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", - "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "title": "Налаштування", + "true_black_dark_mode": "Чорний режим", + "disable_avatar_animation": "Вимкнути анімовані аватари", + "disable_emoji_animation": "Вимкнути анімовані емодзі", + "using_default_browser": "Використовувати браузер за замовчуванням, щоб відкрити посилання", + "open_links_in_mastodon": "Відкривати посилання в Mastodon" }, "boring_zone": { - "title": "The Boring Zone", - "account_settings": "Account Settings", - "terms": "Terms of Service", - "privacy": "Privacy Policy" + "title": "Нудна зона", + "account_settings": "Налаштування облікового запису", + "terms": "Умови використання", + "privacy": "Політика конфіденційності" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", - "signout": "Sign Out" + "title": "Гостра зона", + "clear": "Очистити кеш медіа", + "signout": "Вийти" } }, "footer": { - "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + "mastodon_description": "Mastodon — програма з відкритим вихідним кодом. Ви можете повідомити про проблеми на GitHub на %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Закрити вікно налаштувань" } }, "report": { - "title_report": "Report", - "title": "Report %s", - "step1": "Step 1 of 2", - "step2": "Step 2 of 2", - "content1": "Are there any other posts you’d like to add to the report?", - "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", - "send": "Send Report", - "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED", + "title_report": "Скарга", + "title": "Поскаржитись на %s", + "step1": "Крок 1 з 2", + "step2": "Крок 2 з 2", + "content1": "Чи є інші дописи, які Ви хотіли б додати до скарги?", + "content2": "Чи є що-небудь модератори повинні знати про цю скаргу?", + "report_sent_title": "Дякуємо за скаргу, ми розглянемо її.", + "send": "Надіслати скаргу", + "skip_to_send": "Надіслати без коментаря", + "text_placeholder": "Введіть або вставте додаткові коментарі", + "reported": "Мої скарги", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "step_1_of_4": "Крок 1 з 4", + "whats_wrong_with_this_post": "Що не так з цим постом?", + "whats_wrong_with_this_account": "Що не так з цим обліковим записом?", + "whats_wrong_with_this_username": "Що з %s не так?", + "select_the_best_match": "Оберіть найвідповідніший збіг", + "i_dont_like_it": "Мені це не подобається", + "it_is_not_something_you_want_to_see": "Це не те, що ви хотіли б побачити", + "its_spam": "Це спам", + "malicious_links_fake_engagement_or_repetetive_replies": "Підозрілі посилання, фейкові розмови або відповіді", + "it_violates_server_rules": "Це порушує правила сервера", + "you_are_aware_that_it_breaks_specific_rules": "Ви впевнені, що це порушує певні правила", + "its_something_else": "Це щось інше", + "the_issue_does_not_fit_into_other_categories": "Ця проблема не відповідає жодній іншій категорії" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", - "i_just_don’t_like_it": "I just don’t like it" + "step_2_of_4": "Крок 2 з 4", + "which_rules_are_being_violated": "Які правила порушено?", + "select_all_that_apply": "Виберіть усі варіанти, що підходять", + "i_just_don’t_like_it": "Мені це не подобається" }, "step_three": { - "step_3_of_4": "Step 3 of 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "step_3_of_4": "Крок 3 з 4", + "are_there_any_posts_that_back_up_this_report": "Чи є публікації, які підтверджують цю скаргу?", + "select_all_that_apply": "Виберіть усі варіанти, що підходять" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "Крок 4 з 4", + "is_there_anything_else_we_should_know": "Чи є ще щось, що ми повинні знати?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", - "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "dont_want_to_see_this": "Не хочете бачити це?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Якщо бачите щось, що вам не подобається в Mastodon, то можна вилучити людину зі свого оточення.", + "unfollow": "Відписатися", + "unfollowed": "Відписалися від", + "unfollow_user": "Відписатися від %s", + "mute_user": "Ігнорувати %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Ви не побачите їхні дописи чи репости на вашій домашній стрічці. Вони не знатимуть, що ви ігноруєте їх.", + "block_user": "Заблокувати %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Вони більше не зможуть стежити або бачити Ваші пости, але вони зможуть побачити, що вони були заблоковані.", + "while_we_review_this_you_can_take_action_against_user": "Поки ми переглядаємо це, ви можете вжити заходів проти %s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Закрити перегляд", + "show_next": "Показати наступне", + "show_previous": "Показувати попереднє" } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", - "dismiss_account_switcher": "Dismiss Account Switcher", - "add_account": "Add Account" + "tab_bar_hint": "Поточний профіль: %s. Двічі торкніться, щоб показати перемикач ваших профілів", + "dismiss_account_switcher": "Відхилити зміну поточного облікового запису", + "add_account": "Додати обліковий запис" }, "wizard": { - "new_in_mastodon": "New in Mastodon", - "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", - "accessibility_hint": "Double tap to dismiss this wizard" + "new_in_mastodon": "Новий в Mastodon", + "multiple_account_switch_intro_description": "Натисніть для переходу між кількома обліковими записами, тримаючи кнопку профілю.", + "accessibility_hint": "Двічі торкніться, щоб закрити цей майстер" }, "bookmark": { - "title": "Bookmarks" + "title": "Закладки" } } } From 09cc477fc8e99e6045b6e3ca0f80a887a48d6e7c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:23 +0100 Subject: [PATCH 048/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index f72e178bb..f870bbbfc 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -572,8 +572,8 @@ "followed_you": "mengikutimu", "favorited_your_post": "menyukai postinganmu", "reblogged_your_post": "reblogged your post", - "mentioned_you": "mentioned you", - "request_to_follow_you": "request to follow you", + "mentioned_you": "menyebutmu", + "request_to_follow_you": "meminta mengikutimu", "poll_has_ended": "poll has ended" }, "keyobard": { @@ -581,10 +581,10 @@ "show_mentions": "Tampilkan Sebutan" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Menerima", + "accepted": "Diterima", + "reject": "menolak", + "rejected": "Ditolak" } }, "thread": { @@ -601,11 +601,11 @@ "dark": "Selalu Gelap" }, "look_and_feel": { - "title": "Look and Feel", + "title": "Lihat dan Rasakan", "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "really_dark": "Sangat Gelap", + "sorta_dark": "Agak Gelap", + "light": "Terang" }, "notifications": { "title": "Notifikasi", @@ -617,7 +617,7 @@ "anyone": "siapapun", "follower": "seorang pengikut", "follow": "siapapun yang saya ikuti", - "noone": "no one", + "noone": "tidak ada", "title": "Beritahu saya ketika" } }, @@ -627,7 +627,7 @@ "disable_avatar_animation": "Disable animated avatars", "disable_emoji_animation": "Disable animated emojis", "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "open_links_in_mastodon": "Buka tautan di Mastodon" }, "boring_zone": { "title": "Zona Membosankan", @@ -649,7 +649,7 @@ } }, "report": { - "title_report": "Report", + "title_report": "Laporkan", "title": "Laporkan %s", "step1": "Langkah 1 dari 2", "step2": "Langkah 2 dari 2", @@ -659,13 +659,13 @@ "send": "Kirim Laporan", "skip_to_send": "Kirim tanpa komentar", "text_placeholder": "Ketik atau tempel komentar tambahan", - "reported": "REPORTED", + "reported": "DILAPORKAN", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", + "step_1_of_4": "Langkah 1 dari 4", + "whats_wrong_with_this_post": "Ada yang salah dengan postingan ini?", + "whats_wrong_with_this_account": "Ada yang salah dengan akun ini?", "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", + "select_the_best_match": "Pilih yang paling cocok", "i_dont_like_it": "I don’t like it", "it_is_not_something_you_want_to_see": "It is not something you want to see", "its_spam": "It’s spam", From 036018aa3eab7b63b5f80bd23c37fc534cdab4ae Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:24 +0100 Subject: [PATCH 049/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 727 ++++++++++++++++++ 1 file changed, 727 insertions(+) create mode 100644 Localization/StringsConvertor/input/my.lproj/app.json diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json new file mode 100644 index 000000000..3113ada74 --- /dev/null +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -0,0 +1,727 @@ +{ + "common": { + "alerts": { + "common": { + "please_try_again": "Please try again.", + "please_try_again_later": "Please try again later." + }, + "sign_up_failure": { + "title": "Sign Up Failure" + }, + "server_error": { + "title": "Server Error" + }, + "vote_failure": { + "title": "Vote Failure", + "poll_ended": "The poll has ended" + }, + "discard_post_content": { + "title": "Discard Draft", + "message": "Confirm to discard composed post content." + }, + "publish_post_failure": { + "title": "Publish Failure", + "message": "Failed to publish the post.\nPlease check your internet connection.", + "attachments_message": { + "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", + "more_than_one_video": "Cannot attach more than one video." + } + }, + "edit_profile_failure": { + "title": "Edit Profile Error", + "message": "Cannot edit profile. Please try again." + }, + "sign_out": { + "title": "Sign Out", + "message": "Are you sure you want to sign out?", + "confirm": "Sign Out" + }, + "block_domain": { + "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", + "block_entire_domain": "Block Domain" + }, + "save_photo_failure": { + "title": "Save Photo Failure", + "message": "Please enable the photo library access permission to save the photo." + }, + "delete_post": { + "title": "Delete Post", + "message": "Are you sure you want to delete this post?" + }, + "clean_cache": { + "title": "Clean Cache", + "message": "Successfully cleaned %s cache." + } + }, + "controls": { + "actions": { + "back": "Back", + "next": "Next", + "previous": "Previous", + "open": "Open", + "add": "Add", + "remove": "Remove", + "edit": "Edit", + "save": "Save", + "ok": "OK", + "done": "Done", + "confirm": "Confirm", + "continue": "Continue", + "compose": "Compose", + "cancel": "Cancel", + "discard": "Discard", + "try_again": "Try Again", + "take_photo": "Take Photo", + "save_photo": "Save Photo", + "copy_photo": "Copy Photo", + "sign_in": "Log in", + "sign_up": "Create account", + "see_more": "See More", + "preview": "Preview", + "share": "Share", + "share_user": "Share %s", + "share_post": "Share Post", + "open_in_safari": "Open in Safari", + "open_in_browser": "Open in Browser", + "find_people": "Find people to follow", + "manually_search": "Manually search instead", + "skip": "Skip", + "reply": "Reply", + "report_user": "Report %s", + "block_domain": "Block %s", + "unblock_domain": "Unblock %s", + "settings": "Settings", + "delete": "Delete" + }, + "tabs": { + "home": "Home", + "search": "Search", + "notification": "Notification", + "profile": "Profile" + }, + "keyboard": { + "common": { + "switch_to_tab": "Switch to %s", + "compose_new_post": "Compose New Post", + "show_favorites": "Show Favorites", + "open_settings": "Open Settings" + }, + "timeline": { + "previous_status": "Previous Post", + "next_status": "Next Post", + "open_status": "Open Post", + "open_author_profile": "Open Author's Profile", + "open_reblogger_profile": "Open Reblogger's Profile", + "reply_status": "Reply to Post", + "toggle_reblog": "Toggle Reblog on Post", + "toggle_favorite": "Toggle Favorite on Post", + "toggle_content_warning": "Toggle Content Warning", + "preview_image": "Preview Image" + }, + "segmented_control": { + "previous_section": "Previous Section", + "next_section": "Next Section" + } + }, + "status": { + "user_reblogged": "%s reblogged", + "user_replied_to": "Replied to %s", + "show_post": "Show Post", + "show_user_profile": "Show user profile", + "content_warning": "Content Warning", + "sensitive_content": "Sensitive Content", + "media_content_warning": "Tap anywhere to reveal", + "tap_to_reveal": "Tap to reveal", + "poll": { + "vote": "Vote", + "closed": "Closed" + }, + "meta_entity": { + "url": "Link: %s", + "hashtag": "Hashtag: %s", + "mention": "Show Profile: %s", + "email": "Email address: %s" + }, + "actions": { + "reply": "Reply", + "reblog": "Reblog", + "unreblog": "Undo reblog", + "favorite": "Favorite", + "unfavorite": "Unfavorite", + "menu": "Menu", + "hide": "Hide", + "show_image": "Show image", + "show_gif": "Show GIF", + "show_video_player": "Show video player", + "tap_then_hold_to_show_menu": "Tap then hold to show menu" + }, + "tag": { + "url": "URL", + "mention": "Mention", + "link": "Link", + "hashtag": "Hashtag", + "email": "Email", + "emoji": "Emoji" + }, + "visibility": { + "unlisted": "Everyone can see this post but not display in the public timeline.", + "private": "Only their followers can see this post.", + "private_from_me": "Only my followers can see this post.", + "direct": "Only mentioned user can see this post." + } + }, + "friendship": { + "follow": "Follow", + "following": "Following", + "request": "Request", + "pending": "Pending", + "block": "Block", + "block_user": "Block %s", + "block_domain": "Block %s", + "unblock": "Unblock", + "unblock_user": "Unblock %s", + "blocked": "Blocked", + "mute": "Mute", + "mute_user": "Mute %s", + "unmute": "Unmute", + "unmute_user": "Unmute %s", + "muted": "Muted", + "edit_info": "Edit Info", + "show_reblogs": "Show Reblogs", + "hide_reblogs": "Hide Reblogs" + }, + "timeline": { + "filtered": "Filtered", + "timestamp": { + "now": "Now" + }, + "loader": { + "load_missing_posts": "Load missing posts", + "loading_missing_posts": "Loading missing posts...", + "show_more_replies": "Show more replies" + }, + "header": { + "no_status_found": "No Post Found", + "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", + "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", + "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", + "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "suspended_warning": "This user has been suspended.", + "user_suspended_warning": "%s’s account has been suspended." + } + } + } + }, + "scene": { + "welcome": { + "slogan": "Social networking\nback in your hands.", + "get_started": "Get Started", + "log_in": "Log In" + }, + "login": { + "title": "Welcome back", + "subtitle": "Log you in on the server you created your account on.", + "server_search_field": { + "placeholder": "Enter URL or search for your server" + } + }, + "server_picker": { + "title": "Mastodon is made of users in different servers.", + "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "button": { + "category": { + "all": "All", + "all_accessiblity_description": "Category: All", + "academia": "academia", + "activism": "activism", + "food": "food", + "furry": "furry", + "games": "games", + "general": "general", + "journalism": "journalism", + "lgbt": "lgbt", + "regional": "regional", + "art": "art", + "music": "music", + "tech": "tech" + }, + "see_less": "See Less", + "see_more": "See More" + }, + "label": { + "language": "LANGUAGE", + "users": "USERS", + "category": "CATEGORY" + }, + "input": { + "search_servers_or_enter_url": "Search communities or enter URL" + }, + "empty_state": { + "finding_servers": "Finding available servers...", + "bad_network": "Something went wrong while loading the data. Check your internet connection.", + "no_results": "No results" + } + }, + "register": { + "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "input": { + "avatar": { + "delete": "Delete" + }, + "username": { + "placeholder": "username", + "duplicate_prompt": "This username is taken." + }, + "display_name": { + "placeholder": "display name" + }, + "email": { + "placeholder": "email" + }, + "password": { + "placeholder": "password", + "require": "Your password needs at least:", + "character_limit": "8 characters", + "accessibility": { + "checked": "checked", + "unchecked": "unchecked" + }, + "hint": "Your password needs at least eight characters" + }, + "invite": { + "registration_user_invite_request": "Why do you want to join?" + } + }, + "error": { + "item": { + "username": "Username", + "email": "Email", + "password": "Password", + "agreement": "Agreement", + "locale": "Locale", + "reason": "Reason" + }, + "reason": { + "blocked": "%s contains a disallowed email provider", + "unreachable": "%s does not seem to exist", + "taken": "%s is already in use", + "reserved": "%s is a reserved keyword", + "accepted": "%s must be accepted", + "blank": "%s is required", + "invalid": "%s is invalid", + "too_long": "%s is too long", + "too_short": "%s is too short", + "inclusion": "%s is not a supported value" + }, + "special": { + "username_invalid": "Username must only contain alphanumeric characters and underscores", + "username_too_long": "Username is too long (can’t be longer than 30 characters)", + "email_invalid": "This is not a valid email address", + "password_too_short": "Password is too short (must be at least 8 characters)" + } + } + }, + "server_rules": { + "title": "Some ground rules.", + "subtitle": "These are set and enforced by the %s moderators.", + "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "terms_of_service": "terms of service", + "privacy_policy": "privacy policy", + "button": { + "confirm": "I Agree" + } + }, + "confirm_email": { + "title": "One last thing.", + "subtitle": "Tap the link we emailed to you to verify your account.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "button": { + "open_email_app": "Open Email App", + "resend": "Resend" + }, + "dont_receive_email": { + "title": "Check your email", + "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "resend_email": "Resend Email" + }, + "open_email_app": { + "title": "Check your inbox.", + "description": "We just sent you an email. Check your junk folder if you haven’t.", + "mail": "Mail", + "open_email_client": "Open Email Client" + } + }, + "home_timeline": { + "title": "Home", + "navigation_bar_state": { + "offline": "Offline", + "new_posts": "See new posts", + "published": "Published!", + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } + } + }, + "suggestion_account": { + "title": "Find People to Follow", + "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + }, + "compose": { + "title": { + "new_post": "New Post", + "new_reply": "New Reply" + }, + "media_selection": { + "camera": "Take Photo", + "photo_library": "Photo Library", + "browse": "Browse" + }, + "content_input_placeholder": "Type or paste what’s on your mind", + "compose_action": "Publish", + "replying_to_user": "replying to %s", + "attachment": { + "photo": "photo", + "video": "video", + "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "description_photo": "Describe the photo for the visually-impaired...", + "description_video": "Describe the video for the visually-impaired...", + "load_failed": "Load Failed", + "upload_failed": "Upload Failed", + "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", + "attachment_too_large": "Attachment too large", + "compressing_state": "Compressing...", + "server_processing_state": "Server Processing..." + }, + "poll": { + "duration_time": "Duration: %s", + "thirty_minutes": "30 minutes", + "one_hour": "1 Hour", + "six_hours": "6 Hours", + "one_day": "1 Day", + "three_days": "3 Days", + "seven_days": "7 Days", + "option_number": "Option %ld", + "the_poll_is_invalid": "The poll is invalid", + "the_poll_has_empty_option": "The poll has empty option" + }, + "content_warning": { + "placeholder": "Write an accurate warning here..." + }, + "visibility": { + "public": "Public", + "unlisted": "Unlisted", + "private": "Followers only", + "direct": "Only people I mention" + }, + "auto_complete": { + "space_to_add": "Space to add" + }, + "accessibility": { + "append_attachment": "Add Attachment", + "append_poll": "Add Poll", + "remove_poll": "Remove Poll", + "custom_emoji_picker": "Custom Emoji Picker", + "enable_content_warning": "Enable Content Warning", + "disable_content_warning": "Disable Content Warning", + "post_visibility_menu": "Post Visibility Menu", + "post_options": "Post Options", + "posting_as": "Posting as %s" + }, + "keyboard": { + "discard_post": "Discard Post", + "publish_post": "Publish Post", + "toggle_poll": "Toggle Poll", + "toggle_content_warning": "Toggle Content Warning", + "append_attachment_entry": "Add Attachment - %s", + "select_visibility_entry": "Select Visibility - %s" + } + }, + "profile": { + "header": { + "follows_you": "Follows You" + }, + "dashboard": { + "posts": "posts", + "following": "following", + "followers": "followers" + }, + "fields": { + "add_row": "Add Row", + "placeholder": { + "label": "Label", + "content": "Content" + }, + "verified": { + "short": "Verified on %s", + "long": "Ownership of this link was checked on %s" + } + }, + "segmented_control": { + "posts": "Posts", + "replies": "Replies", + "posts_and_replies": "Posts and Replies", + "media": "Media", + "about": "About" + }, + "relationship_action_alert": { + "confirm_mute_user": { + "title": "Mute Account", + "message": "Confirm to mute %s" + }, + "confirm_unmute_user": { + "title": "Unmute Account", + "message": "Confirm to unmute %s" + }, + "confirm_block_user": { + "title": "Block Account", + "message": "Confirm to block %s" + }, + "confirm_unblock_user": { + "title": "Unblock Account", + "message": "Confirm to unblock %s" + }, + "confirm_show_reblogs": { + "title": "Show Reblogs", + "message": "Confirm to show reblogs" + }, + "confirm_hide_reblogs": { + "title": "Hide Reblogs", + "message": "Confirm to hide reblogs" + } + }, + "accessibility": { + "show_avatar_image": "Show avatar image", + "edit_avatar_image": "Edit avatar image", + "show_banner_image": "Show banner image", + "double_tap_to_open_the_list": "Double tap to open the list" + } + }, + "follower": { + "title": "follower", + "footer": "Followers from other servers are not displayed." + }, + "following": { + "title": "following", + "footer": "Follows from other servers are not displayed." + }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, + "search": { + "title": "Search", + "search_bar": { + "placeholder": "Search hashtags and users", + "cancel": "Cancel" + }, + "recommend": { + "button_text": "See All", + "hash_tag": { + "title": "Trending on Mastodon", + "description": "Hashtags that are getting quite a bit of attention", + "people_talking": "%s people are talking" + }, + "accounts": { + "title": "Accounts you might like", + "description": "You may like to follow these accounts", + "follow": "Follow" + } + }, + "searching": { + "segment": { + "all": "All", + "people": "People", + "hashtags": "Hashtags", + "posts": "Posts" + }, + "empty_state": { + "no_results": "No results" + }, + "recent_search": "Recent searches", + "clear": "Clear" + } + }, + "discovery": { + "tabs": { + "posts": "Posts", + "hashtags": "Hashtags", + "news": "News", + "community": "Community", + "for_you": "For You" + }, + "intro": "These are the posts gaining traction in your corner of Mastodon." + }, + "favorite": { + "title": "Your Favorites" + }, + "notification": { + "title": { + "Everything": "Everything", + "Mentions": "Mentions" + }, + "notification_description": { + "followed_you": "followed you", + "favorited_your_post": "favorited your post", + "reblogged_your_post": "reblogged your post", + "mentioned_you": "mentioned you", + "request_to_follow_you": "request to follow you", + "poll_has_ended": "poll has ended" + }, + "keyobard": { + "show_everything": "Show Everything", + "show_mentions": "Show Mentions" + }, + "follow_request": { + "accept": "Accept", + "accepted": "Accepted", + "reject": "reject", + "rejected": "Rejected" + } + }, + "thread": { + "back_title": "Post", + "title": "Post from %s" + }, + "settings": { + "title": "Settings", + "section": { + "appearance": { + "title": "Appearance", + "automatic": "Automatic", + "light": "Always Light", + "dark": "Always Dark" + }, + "look_and_feel": { + "title": "Look and Feel", + "use_system": "Use System", + "really_dark": "Really Dark", + "sorta_dark": "Sorta Dark", + "light": "Light" + }, + "notifications": { + "title": "Notifications", + "favorites": "Favorites my post", + "follows": "Follows me", + "boosts": "Reblogs my post", + "mentions": "Mentions me", + "trigger": { + "anyone": "anyone", + "follower": "a follower", + "follow": "anyone I follow", + "noone": "no one", + "title": "Notify me when" + } + }, + "preference": { + "title": "Preferences", + "true_black_dark_mode": "True black dark mode", + "disable_avatar_animation": "Disable animated avatars", + "disable_emoji_animation": "Disable animated emojis", + "using_default_browser": "Use default browser to open links", + "open_links_in_mastodon": "Open links in Mastodon" + }, + "boring_zone": { + "title": "The Boring Zone", + "account_settings": "Account Settings", + "terms": "Terms of Service", + "privacy": "Privacy Policy" + }, + "spicy_zone": { + "title": "The Spicy Zone", + "clear": "Clear Media Cache", + "signout": "Sign Out" + } + }, + "footer": { + "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + }, + "keyboard": { + "close_settings_window": "Close Settings Window" + } + }, + "report": { + "title_report": "Report", + "title": "Report %s", + "step1": "Step 1 of 2", + "step2": "Step 2 of 2", + "content1": "Are there any other posts you’d like to add to the report?", + "content2": "Is there anything the moderators should know about this report?", + "report_sent_title": "Thanks for reporting, we’ll look into this.", + "send": "Send Report", + "skip_to_send": "Send without comment", + "text_placeholder": "Type or paste additional comments", + "reported": "REPORTED", + "step_one": { + "step_1_of_4": "Step 1 of 4", + "whats_wrong_with_this_post": "What's wrong with this post?", + "whats_wrong_with_this_account": "What's wrong with this account?", + "whats_wrong_with_this_username": "What's wrong with %s?", + "select_the_best_match": "Select the best match", + "i_dont_like_it": "I don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "it_violates_server_rules": "It violates server rules", + "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "its_something_else": "It’s something else", + "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + }, + "step_two": { + "step_2_of_4": "Step 2 of 4", + "which_rules_are_being_violated": "Which rules are being violated?", + "select_all_that_apply": "Select all that apply", + "i_just_don’t_like_it": "I just don’t like it" + }, + "step_three": { + "step_3_of_4": "Step 3 of 4", + "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", + "select_all_that_apply": "Select all that apply" + }, + "step_four": { + "step_4_of_4": "Step 4 of 4", + "is_there_anything_else_we_should_know": "Is there anything else we should know?" + }, + "step_final": { + "dont_want_to_see_this": "Don’t want to see this?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "unfollow": "Unfollow", + "unfollowed": "Unfollowed", + "unfollow_user": "Unfollow %s", + "mute_user": "Mute %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "block_user": "Block %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } + }, + "preview": { + "keyboard": { + "close_preview": "Close Preview", + "show_next": "Show Next", + "show_previous": "Show Previous" + } + }, + "account_list": { + "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", + "dismiss_account_switcher": "Dismiss Account Switcher", + "add_account": "Add Account" + }, + "wizard": { + "new_in_mastodon": "New in Mastodon", + "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", + "accessibility_hint": "Double tap to dismiss this wizard" + }, + "bookmark": { + "title": "Bookmarks" + } + } +} From 04f556571adf46c04b16eb2ac84cc972dac8f118 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:25 +0100 Subject: [PATCH 050/733] New translations ios-infoPlist.json (Burmese) --- .../StringsConvertor/input/my.lproj/ios-infoPlist.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json new file mode 100644 index 000000000..c6db73de0 --- /dev/null +++ b/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json @@ -0,0 +1,6 @@ +{ + "NSCameraUsageDescription": "Used to take photo for post status", + "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NewPostShortcutItemTitle": "New Post", + "SearchShortcutItemTitle": "Search" +} From 94afbc95f0a9531aa90aa1379c16b33202ace598 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:26 +0100 Subject: [PATCH 051/733] New translations Localizable.stringsdict (Burmese) --- .../input/my.lproj/Localizable.stringsdict | 407 ++++++++++++++++++ 1 file changed, 407 insertions(+) create mode 100644 Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict diff --git a/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict new file mode 100644 index 000000000..5001ec5cb --- /dev/null +++ b/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict @@ -0,0 +1,407 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + မဖတ်ရသေးသောအသိပေးချက် %ld ခု ရှိသည် + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + စာလုံးရေ သတ်မှတ်ချက်ထက် %#@character_count@ လုံး ထက်ကျော်လွန် + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + စာလုံး %ld လုံး + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + သတ်မှတ်စာလုံးရေ %#@character_count@ လုံး ကျန်ရှိ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + စာလုံး %ld လုံး + + + a11y.plural.count.characters_left + + NSStringLocalizedFormatKey + စာလုံးရေ %#@character_count@ လုံး ကျန်ရှိ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld characters + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Followed by %1$@, and %ld mutuals + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + posts + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld posts + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld favorites + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld reblogs + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld replies + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld votes + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld voters + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld people talking + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld following + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld followers + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld years left + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld months left + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld days left + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld hours left + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld minutes left + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld seconds left + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ldy ago + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ldM ago + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ldd ago + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ldh ago + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ldm ago + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %lds ago + + + + From c6759d2e62e2a10f2fdcfb341a52606131f52754 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:27 +0100 Subject: [PATCH 052/733] New translations Intents.strings (Burmese) --- .../Intents/input/my.lproj/Intents.strings | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings new file mode 100644 index 000000000..6877490ba --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Post on Mastodon"; + +"751xkl" = "Text Content"; + +"CsR7G2" = "Post on Mastodon"; + +"HZSGTr" = "What content to post?"; + +"HdGikU" = "Posting failed"; + +"KDNTJ4" = "Failure Reason"; + +"RHxKOw" = "Send Post with text content"; + +"RxSqsb" = "Post"; + +"WCIR3D" = "Post ${content} on Mastodon"; + +"ZKJSNu" = "Post"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Visibility"; + +"Zo4jgJ" = "Post Visibility"; + +"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; + +"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; + +"ayoYEb-dYQ5NN" = "${content}, Public"; + +"ayoYEb-ehFLjY" = "${content}, Followers Only"; + +"dUyuGg" = "Post on Mastodon"; + +"dYQ5NN" = "Public"; + +"ehFLjY" = "Followers Only"; + +"gfePDu" = "Posting failed. ${failureReason}"; + +"k7dbKQ" = "Post was sent successfully."; + +"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; + +"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Post was sent successfully. "; From ae69f1e33ceef5f399a9e87fb980e0ff6fa29921 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 16:31:28 +0100 Subject: [PATCH 053/733] New translations Intents.stringsdict (Burmese) --- .../input/my.lproj/Intents.stringsdict | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict new file mode 100644 index 000000000..a14f8b9ff --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict @@ -0,0 +1,34 @@ + + + + + There are ${count} options matching ‘${content}’. - 2 + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${content}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + other + %ld options + + + There are ${count} options matching ‘${visibility}’. + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${visibility}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + other + %ld options + + + + From ffaf1f19d69620fd46d35fd89bbda52916334b09 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 17:37:12 +0100 Subject: [PATCH 054/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 3113ada74..a563c9d37 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -2,39 +2,39 @@ "common": { "alerts": { "common": { - "please_try_again": "Please try again.", - "please_try_again_later": "Please try again later." + "please_try_again": "ပြန်လည်ကြိုးစားကြည့်ပါ", + "please_try_again_later": "နောက်မှ ပြန်လည်ကြိုးစားကြည့်ပါ" }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "အကောင့်ဖွင့်ခြင်း မအောင်မြင်ပါ" }, "server_error": { - "title": "Server Error" + "title": "ဆာဗာ အမှား" }, "vote_failure": { - "title": "Vote Failure", - "poll_ended": "The poll has ended" + "title": "မဲပေးမှု မအောင်မြင်ခြင်း", + "poll_ended": "စစ်တမ်းကောက်မှု ပြီးဆုံးပါပြီ" }, "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." + "title": "မူကြမ်းကို ပယ်ဖျက်ပါ", + "message": "ရေးသားထားသောမူကြမ်းကို ပယ်ဖျက်ရန် အတည်ပြုပါ" }, "publish_post_failure": { - "title": "Publish Failure", - "message": "Failed to publish the post.\nPlease check your internet connection.", + "title": "ပို့စ်တင်ခြင်း မအောင်မြင်မှု", + "message": "ပို့စ်တင်ခြင်း မအောင်မြင်ပါ၊ သင်၏ အင်တာနက်ချိတ်ဆက်မှုကို စစ်ဆေးပါ။", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", - "more_than_one_video": "Cannot attach more than one video." + "video_attach_with_photo": "ဓာတ်ပုံများပါဝင်သော ပို့စ်တွင် ဗီဒီိယိုကို တွဲတင်၍ မရပါ", + "more_than_one_video": "ဗီဒီိယို ၁ ခုထက်ပို၍ တွဲတင်၍ မရပါ" } }, "edit_profile_failure": { - "title": "Edit Profile Error", - "message": "Cannot edit profile. Please try again." + "title": "ပရိုဖိုင်ပြင်ဆင်ခြင်း အမှား", + "message": "ပရိုဖိုင်ကို ပြင်ဆင်၍ မရပါ၊ ပြန်လည်ကြိုးစားကြည့်ပါ။" }, "sign_out": { - "title": "Sign Out", - "message": "Are you sure you want to sign out?", - "confirm": "Sign Out" + "title": "ထွက်မည်", + "message": "အကောင့်မှ ထွက်ရန် သေချာပါသလား?", + "confirm": "ထွက်မည်" }, "block_domain": { "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", From cca425c6de60df4fdf182d0201f564a5a986eb5e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 17:37:13 +0100 Subject: [PATCH 055/733] New translations Localizable.stringsdict (Burmese) --- .../input/my.lproj/Localizable.stringsdict | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict index 5001ec5cb..8230962a5 100644 --- a/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/my.lproj/Localizable.stringsdict @@ -55,7 +55,7 @@ NSStringFormatValueTypeKey ld other - %ld characters + စာလုံး %ld လုံး plural.count.followed_by_and_mutual @@ -78,7 +78,7 @@ NSStringFormatValueTypeKey ld other - Followed by %1$@, and %ld mutuals + %1$@ နှင့် ဘုံသူငယ်ချင်း %ld ဦးမှ စောင့်ကြည့်နေသည် plural.count.metric_formatted.post @@ -92,7 +92,7 @@ NSStringFormatValueTypeKey ld other - posts + ပို့စ်များ plural.count.media @@ -106,7 +106,7 @@ NSStringFormatValueTypeKey ld other - %ld media + ရုပ်သံ %ld ခု plural.count.post @@ -120,7 +120,7 @@ NSStringFormatValueTypeKey ld other - %ld posts + ပို့စ် %ld ခု plural.count.favorite @@ -134,7 +134,7 @@ NSStringFormatValueTypeKey ld other - %ld favorites + အကြိုက်ဆုံး %ld ခု plural.count.reblog @@ -148,7 +148,7 @@ NSStringFormatValueTypeKey ld other - %ld reblogs + ပြန်မျှဝေမှု %ld ခု plural.count.reply @@ -162,7 +162,7 @@ NSStringFormatValueTypeKey ld other - %ld replies + ပြန်စာ %ld ခု plural.count.vote @@ -176,7 +176,7 @@ NSStringFormatValueTypeKey ld other - %ld votes + မဲ %ld မဲ plural.count.voter @@ -190,7 +190,7 @@ NSStringFormatValueTypeKey ld other - %ld voters + မဲပေးသူ %ld ဦး plural.people_talking @@ -204,7 +204,7 @@ NSStringFormatValueTypeKey ld other - %ld people talking + လူ %ld ဦး ပြောနေသည် plural.count.following @@ -218,7 +218,7 @@ NSStringFormatValueTypeKey ld other - %ld following + စောင့်ကြည့်သူ %ld ဦး plural.count.follower @@ -232,7 +232,7 @@ NSStringFormatValueTypeKey ld other - %ld followers + စောင့်ကြည့်သူ %ld ဦး date.year.left @@ -246,7 +246,7 @@ NSStringFormatValueTypeKey ld other - %ld years left + %ld နှစ် ကျန်ရှိ date.month.left @@ -260,7 +260,7 @@ NSStringFormatValueTypeKey ld other - %ld months left + %ld လ ကျန်ရှိ date.day.left @@ -274,7 +274,7 @@ NSStringFormatValueTypeKey ld other - %ld days left + %ld ရက် ကျန်ရှိ date.hour.left @@ -288,7 +288,7 @@ NSStringFormatValueTypeKey ld other - %ld hours left + %ld နာရီ ကျန်ရှိ date.minute.left @@ -302,7 +302,7 @@ NSStringFormatValueTypeKey ld other - %ld minutes left + %ld မိနစ် ကျန်ရှိ date.second.left @@ -316,7 +316,7 @@ NSStringFormatValueTypeKey ld other - %ld seconds left + %ld စက္ကန့် ကျန်ရှိ date.year.ago.abbr @@ -330,7 +330,7 @@ NSStringFormatValueTypeKey ld other - %ldy ago + လွန်ခဲ့သော %ld နှစ်က date.month.ago.abbr @@ -344,7 +344,7 @@ NSStringFormatValueTypeKey ld other - %ldM ago + လွန်ခဲ့သော %ld လက date.day.ago.abbr @@ -358,7 +358,7 @@ NSStringFormatValueTypeKey ld other - %ldd ago + လွန်ခဲ့သော %ld ရက်က date.hour.ago.abbr @@ -372,7 +372,7 @@ NSStringFormatValueTypeKey ld other - %ldh ago + လွန်ခဲ့သော %ld နာရီက date.minute.ago.abbr @@ -386,7 +386,7 @@ NSStringFormatValueTypeKey ld other - %ldm ago + လွန်ခဲ့သော %ld မိနစ်က date.second.ago.abbr @@ -400,7 +400,7 @@ NSStringFormatValueTypeKey ld other - %lds ago + လွန်ခဲ့သော %ld စက္ကန့်က From 5873c4053c7c6f16af7b97c9925fe3d277f59f4d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 17:37:14 +0100 Subject: [PATCH 056/733] New translations Intents.strings (Burmese) --- .../Intents/input/my.lproj/Intents.strings | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings index 6877490ba..8fd6a698c 100644 --- a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.strings @@ -1,51 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Mastodon တွင် ပို့စ်တင်ရန်"; -"751xkl" = "Text Content"; +"751xkl" = "အကြောင်းအရာ"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Mastodon တွင် ပို့စ်တင်ရန်"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "ဘယ်အကြောင်းအရာကို ပို့စ်တင်မလဲ?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "ပို့စ်တင််ခြင်း မအောင်မြင်ပါ"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "မအောင်မြင်ရသည့် အကြောင်းပြချက်"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "ပို့စ်ကို အကြောင်းအရာနှင့်တကွ တင်ရန်"; -"RxSqsb" = "Post"; +"RxSqsb" = "ပို့စ်"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "${content} ကို Mastodon တွင် ပိုစ့်တင်ရန်"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "ပို့စ်"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "မြင်နိုင်မှု"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "ပို့်စ်မြင်နိုင်မှု"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "‘Public’ နှင့် ကိုက်ညီသော ရွေးချယ်စရာ ${count} ခု ရှိသည်။"; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "‘Followers Only’ နှင့် ကိုက်ညီသော ရွေးချယ်စရာ ${count} ခု ရှိသည်။"; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, အများမြင်"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, စောင့်ကြည့်သူများ သီးသန့်"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Mastodon တွင် ပို့စ်တင်ရန်"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "အများမြင်"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "စောင့်ကြည့်သူများသီးသန့်"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "ပို့စ်တင််ခြင်း မအောင်မြင်ပါ၊ ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "ပို့စ်ကို အောင်မြင်စွာ ပို့ခဲ့သည်"; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "\"အများမြင်\" ကို ရွေးမည်် သေချာပါသလား?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "\"စောင့်ကြည့်သူများသီးသန့်\" ကို ရွေးမည်် သေချာပါသလား?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "ပို့စ်ကို အောင်မြင်စွာ ပို့ခဲ့သည်"; From 84953facb6fb20dd33299823dc3011edf7bfd577 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 18:47:17 +0100 Subject: [PATCH 057/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index a563c9d37..c503cec55 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -37,49 +37,49 @@ "confirm": "ထွက်မည်" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", - "block_entire_domain": "Block Domain" + "title": "%s တစ်ခုလုံးကို ဘလော့လုပ်ရန် တကယ် သေချာပါသလား? များသောအားဖြင့် အနည်းစုကို ပစ်မှတ်ထား ဘလော့လုပ်ခြင်းသည် လုံလောက်ပါသည်။ ထို ဒိုမိန်းမှ အကြောင်းအရာ တစ်ခုမှ မြင်ရမည်မဟုတ်သည့်အပြင် ထို ဒိုမိန်းတွင်ရှိသော သင်၏ စောင့်ကြည့်သူများပါ ဖယ်ရှားပစ်မည်ဖြစ်သည်။", + "block_entire_domain": "ဒိုမိန်းကို ဘလော့လုပ်ရန်" }, "save_photo_failure": { - "title": "Save Photo Failure", - "message": "Please enable the photo library access permission to save the photo." + "title": "ဓာတ်ပုံသိမ်းဆည်းခြင်း အမှား", + "message": "ကျေးဇူးပြု၍ ဓာတ်ပုံသိမ်းဆည်းနိုင်ရန် ဓာတ်ပုံပြတိုက်သို့ ဝင်ရောက်ခွင့်ပေးပါ။" }, "delete_post": { - "title": "Delete Post", - "message": "Are you sure you want to delete this post?" + "title": "ပို့စ်ဖျက်ရန်", + "message": "ပို့စ်ကို ဖျက်ရန် သေချာပါသလား?" }, "clean_cache": { - "title": "Clean Cache", - "message": "Successfully cleaned %s cache." + "title": "Cache ကို ရှင်းပါ", + "message": "%s cache ကို အောင်မြင်စွာ ရှင်းလင်းပြီးပါပြီ" } }, "controls": { "actions": { - "back": "Back", - "next": "Next", - "previous": "Previous", - "open": "Open", - "add": "Add", - "remove": "Remove", - "edit": "Edit", - "save": "Save", - "ok": "OK", - "done": "Done", - "confirm": "Confirm", - "continue": "Continue", - "compose": "Compose", - "cancel": "Cancel", - "discard": "Discard", - "try_again": "Try Again", - "take_photo": "Take Photo", - "save_photo": "Save Photo", - "copy_photo": "Copy Photo", - "sign_in": "Log in", - "sign_up": "Create account", - "see_more": "See More", - "preview": "Preview", - "share": "Share", - "share_user": "Share %s", + "back": "ပြန်၍", + "next": "ရှေ့သို့", + "previous": "ယခင်", + "open": "ဖွင့်", + "add": "ထည့်", + "remove": "ဖယ်ရှား", + "edit": "တည်းဖြတ်", + "save": "သိမ်းဆည်း", + "ok": "အိုကေ", + "done": "ပြီးပြီ", + "confirm": "အတည်ပြု", + "continue": "ဆက်လက်", + "compose": "ရေးဖွဲ့", + "cancel": "ပယ်ဖျက်", + "discard": "ဖယ်ရှား", + "try_again": "ထပ်မံကြိုးစားပါ", + "take_photo": "ဓါတ်ပုံရိုက်", + "save_photo": "ဓါတ်ပုံသိမ်းဆည်း", + "copy_photo": "ဓာတ်ပုံကူး", + "sign_in": "လော့ဂ်အင်ဝင်", + "sign_up": "အကောင့်ဖန်တီး", + "see_more": "ပိုမိုကြည့်ရှုရန်", + "preview": "အစမ်းကြည့်", + "share": "မျှဝေ", + "share_user": "%s ကို မျှဝေပါ", "share_post": "Share Post", "open_in_safari": "Open in Safari", "open_in_browser": "Open in Browser", @@ -147,34 +147,34 @@ "reblog": "Reblog", "unreblog": "Undo reblog", "favorite": "Favorite", - "unfavorite": "Unfavorite", - "menu": "Menu", - "hide": "Hide", - "show_image": "Show image", - "show_gif": "Show GIF", - "show_video_player": "Show video player", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "unfavorite": "အကြိုက်ဆုံးမှ ဖယ်ရှားရန်", + "menu": "မီနူး", + "hide": "ဝှက်ရန်", + "show_image": "ဓာတ်ပုံပြရန်", + "show_gif": "GIF ပြရန်", + "show_video_player": "ဗီဒီယိုဖွင့်စက် ပြရန်", + "tap_then_hold_to_show_menu": "မီနူးပြရန် ဖိထားပါ" }, "tag": { "url": "URL", - "mention": "Mention", - "link": "Link", - "hashtag": "Hashtag", - "email": "Email", - "emoji": "Emoji" + "mention": "ရည်ညွှန်း", + "link": "လင့်ခ်", + "hashtag": "ဟက်ရှ်တက်ခ်", + "email": "အီးမေးလ်", + "emoji": "အီမိုဂျီ" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "ဒီပို့စ်ကို လူတိုင်းမြင်နိုင်သည်၊ သို့သော် အများမြင်အလင်းစဉ်တွင် မပြသပါ။", + "private": "သူတို့၏ စောင့်ကြည့်သူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်", + "private_from_me": "ကျွန်ုပ်၏ စောင့်ကြည့်သူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်", + "direct": "ရည်ညွှန်းခံရသောအသုံးပြုသူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်" } }, "friendship": { - "follow": "Follow", - "following": "Following", - "request": "Request", - "pending": "Pending", + "follow": "စောင့်ကြည့်ရန်", + "following": "စောင့်ကြည့်နေသည်", + "request": "တောင်းဆို", + "pending": "ဆိုင်းငံ့ထားသည်", "block": "Block", "block_user": "Block %s", "block_domain": "Block %s", From bd4e8b1cb43f1ec435315f14f8c16872ee621acc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 19:52:07 +0100 Subject: [PATCH 058/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 894a0245e..51a163f37 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -500,11 +500,11 @@ } }, "follower": { - "title": "Follower", - "footer": "Folger, die nicht auf deinem Server registriert sind, werden nicht angezeigt." + "title": "Folgende", + "footer": "Folgende, die nicht auf deinem Server registriert sind, werden nicht angezeigt." }, "following": { - "title": "Folgende", + "title": "Gefolgte", "footer": "Gefolgte, die nicht auf deinem Server registriert sind, werden nicht angezeigt." }, "familiarFollowers": { From eb4a62025baf2714c4f9aeee94ef8c5ca55b75d6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 21:04:24 +0100 Subject: [PATCH 059/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 51a163f37..1bd5def6d 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -172,7 +172,7 @@ }, "friendship": { "follow": "Folgen", - "following": "Folge Ich", + "following": "Gefolgt", "request": "Anfragen", "pending": "In Warteschlange", "block": "Blockieren", @@ -367,7 +367,7 @@ }, "suggestion_account": { "title": "Finde Personen zum Folgen", - "follow_explain": "Wenn du jemandem folgst, dann siehst du deren Beiträge in deinem Home-Feed." + "follow_explain": "Sobald du anderen folgst, siehst du deren Beiträge in deinem Home-Feed." }, "compose": { "title": { @@ -508,7 +508,7 @@ "footer": "Gefolgte, die nicht auf deinem Server registriert sind, werden nicht angezeigt." }, "familiarFollowers": { - "title": "Follower, die dir bekannt vorkommen", + "title": "Folgende, die du kennst", "followed_by_names": "Gefolgt von %s" }, "favorited_by": { From 08de8b21d978fe2761eeeaace986c58e59df1db6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 22:10:29 +0100 Subject: [PATCH 060/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 1bd5def6d..4ad5fd3e0 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -139,8 +139,8 @@ "meta_entity": { "url": "Link: %s", "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "mention": "Profil anzeigen: %s", + "email": "E-Mail-Adresse: %s" }, "actions": { "reply": "Antworten", @@ -165,8 +165,8 @@ }, "visibility": { "unlisted": "Jeder kann diesen Post sehen, aber nicht in der öffentlichen Timeline zeigen.", - "private": "Nur Follower des Authors können diesen Beitrag sehen.", - "private_from_me": "Nur meine Follower können diesen Beitrag sehen.", + "private": "Nur die, die dem Autor folgen, können diesen Beitrag sehen.", + "private_from_me": "Nur die, die mir folgen, können diesen Beitrag sehen.", "direct": "Nur erwähnte Benutzer können diesen Beitrag sehen." } }, @@ -348,7 +348,7 @@ "open_email_app": { "title": "Überprüfe deinen Posteingang.", "description": "Wir haben dir gerade eine E-Mail geschickt. Überprüfe deinen Spam-Ordner, falls du es noch nicht getan hast.", - "mail": "Mail", + "mail": "E-Mail", "open_email_client": "E-Mail-Client öffnen" } }, @@ -427,8 +427,8 @@ "enable_content_warning": "Inhaltswarnung einschalten", "disable_content_warning": "Inhaltswarnung ausschalten", "post_visibility_menu": "Sichtbarkeitsmenü", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Beitragsoptionen", + "posting_as": "Posten als %s" }, "keyboard": { "discard_post": "Beitrag verwerfen", @@ -485,11 +485,11 @@ }, "confirm_show_reblogs": { "title": "Reblogs anzeigen", - "message": "Bestätigen um Reblogs anzuzeigen" + "message": "Bestätigen, um Teilen anzuzeigen" }, "confirm_hide_reblogs": { - "title": "Reblogs ausblenden", - "message": "Confirm to hide reblogs" + "title": "Teilen ausblenden", + "message": "Bestätigen, um Teilen auszublenden" } }, "accessibility": { @@ -532,7 +532,7 @@ }, "accounts": { "title": "Konten, die dir gefallen könnten", - "description": "Vielleicht gefallen dir diese Benutzer", + "description": "Vielleicht gefallen dir diese Konten", "follow": "Folgen" } }, From a92e753d7e1f63d3cbc86020fde66b046925fecc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 23:11:36 +0100 Subject: [PATCH 061/733] New translations Localizable.stringsdict (German) --- .../input/de.lproj/Localizable.stringsdict | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict index 1965fd02b..9d07f80d1 100644 --- a/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict @@ -37,7 +37,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Noch %#@character_count@ übrig + Noch %#@character_count@ Zeichen übrig character_count NSStringFormatSpecTypeKey @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ übrig character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 Zeichen other - %ld characters + %ld Zeichen plural.count.followed_by_and_mutual From e9ef405cbb53965240cb5686746de961c79373f1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Nov 2022 23:11:38 +0100 Subject: [PATCH 062/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 4ad5fd3e0..65a315b5c 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -187,8 +187,8 @@ "unmute_user": "%s nicht mehr stummschalten", "muted": "Stummgeschaltet", "edit_info": "Information bearbeiten", - "show_reblogs": "Reblogs anzeigen", - "hide_reblogs": "Reblogs ausblenden" + "show_reblogs": "Teilen anzeigen", + "hide_reblogs": "Teilen ausblenden" }, "timeline": { "filtered": "Gefiltert", @@ -484,7 +484,7 @@ "message": "Bestätige %s zu entsperren" }, "confirm_show_reblogs": { - "title": "Reblogs anzeigen", + "title": "Teilen anzeigen", "message": "Bestätigen, um Teilen anzuzeigen" }, "confirm_hide_reblogs": { From c498bcee823e4df8d793b0308a8f7c79863480dd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 00:25:39 +0100 Subject: [PATCH 063/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index f73faabd4..7df97e6f2 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -72,9 +72,9 @@ "discard": "破棄", "try_again": "再実行", "take_photo": "写真を撮る", - "save_photo": "写真を撮る", + "save_photo": "写真を保存", "copy_photo": "写真をコピー", - "sign_in": "Log in", + "sign_in": "ログイン", "sign_up": "Create account", "see_more": "もっと見る", "preview": "プレビュー", @@ -427,7 +427,7 @@ "enable_content_warning": "閲覧注意を有効にする", "disable_content_warning": "閲覧注意を無効にする", "post_visibility_menu": "投稿の表示メニュー", - "post_options": "Post Options", + "post_options": "投稿オプション", "posting_as": "Posting as %s" }, "keyboard": { @@ -678,7 +678,7 @@ "step_two": { "step_2_of_4": "ステップ 2/4", "which_rules_are_being_violated": "どのルールに違反していますか?", - "select_all_that_apply": "Select all that apply", + "select_all_that_apply": "当てはまるものをすべて選んでください", "i_just_don’t_like_it": "I just don’t like it" }, "step_three": { @@ -721,7 +721,7 @@ "accessibility_hint": "チュートリアルを閉じるには、ダブルタップしてください" }, "bookmark": { - "title": "Bookmarks" + "title": "ブックマーク" } } } From 3283906b08d511845ac1206ac19eb216cc105faf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 01:23:31 +0100 Subject: [PATCH 064/733] New translations app.json (Japanese) --- .../StringsConvertor/input/ja.lproj/app.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 7df97e6f2..4f8d5f578 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -335,7 +335,7 @@ "confirm_email": { "title": "さいごにもうひとつ。", "subtitle": "先程 %s にメールを送信しました。リンクをタップしてアカウントを確認してください。", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "メールで送られたリンクへアクセスし、アカウントを認証してください", "button": { "open_email_app": "メールアプリを開く", "resend": "再送信" @@ -388,10 +388,10 @@ "attachment_broken": "%sは壊れていてMastodonにアップロードできません。", "description_photo": "閲覧が難しいユーザーへの画像説明", "description_video": "閲覧が難しいユーザーへの映像説明", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", + "load_failed": "読み込みに失敗しました", + "upload_failed": "アップロードに失敗しました", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", + "attachment_too_large": "添付ファイルが大きすぎます", "compressing_state": "Compressing...", "server_processing_state": "Server Processing..." }, @@ -420,7 +420,7 @@ "space_to_add": "スペースを追加" }, "accessibility": { - "append_attachment": "アタッチメントの追加", + "append_attachment": "添付ファイルを追加", "append_poll": "投票を追加", "remove_poll": "投票を消去", "custom_emoji_picker": "カスタム絵文字ピッカー", @@ -435,7 +435,7 @@ "publish_post": "投稿する", "toggle_poll": "投票を切り替える", "toggle_content_warning": "閲覧注意を切り替える", - "append_attachment_entry": "アタッチメントを追加 - %s", + "append_attachment_entry": "添付ファイルを追加 - %s", "select_visibility_entry": "公開設定を選択 - %s" } }, @@ -679,27 +679,27 @@ "step_2_of_4": "ステップ 2/4", "which_rules_are_being_violated": "どのルールに違反していますか?", "select_all_that_apply": "当てはまるものをすべて選んでください", - "i_just_don’t_like_it": "I just don’t like it" + "i_just_don’t_like_it": "興味がありません" }, "step_three": { "step_3_of_4": "ステップ 3/4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "are_there_any_posts_that_back_up_this_report": "この通報を裏付けるような投稿はありますか?", + "select_all_that_apply": "当てはまるものをすべて選んでください" }, "step_four": { "step_4_of_4": "ステップ 4/4", "is_there_anything_else_we_should_know": "その他に私たちに伝えておくべき事はありますか?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "dont_want_to_see_this": "見えないようにしたいですか?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Mastodonで気に入らないものを見た場合、その人をあなたの体験から取り除くことができます。", "unfollow": "フォロー解除", "unfollowed": "フォロー解除しました", "unfollow_user": "%sをフォロー解除", "mute_user": "%sをミュート", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "ホームに投稿やブーストは表示されなくなります。相手にミュートしたことは伝わりません。", "block_user": "%sをブロック", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "相手はあなたの投稿を見たり、フォローしたりできなくなります。あなたにブロックされていることはわかります。", "while_we_review_this_you_can_take_action_against_user": "私たちが確認している間でも、あなたは%sさんに対して対応することができます。" } }, From 4264c9fb64e049085a8fe5047b1aa72e70f47253 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 05:20:38 +0100 Subject: [PATCH 065/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index c503cec55..c4b6bbe32 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -80,73 +80,73 @@ "preview": "အစမ်းကြည့်", "share": "မျှဝေ", "share_user": "%s ကို မျှဝေပါ", - "share_post": "Share Post", - "open_in_safari": "Open in Safari", - "open_in_browser": "Open in Browser", - "find_people": "Find people to follow", - "manually_search": "Manually search instead", - "skip": "Skip", - "reply": "Reply", - "report_user": "Report %s", - "block_domain": "Block %s", - "unblock_domain": "Unblock %s", - "settings": "Settings", - "delete": "Delete" + "share_post": "ပို့စ်ကို မျှဝေရန်", + "open_in_safari": "Safari တွင် ဖွင့်ရန်", + "open_in_browser": "Browser တွင် ဖွင့်ရန်", + "find_people": "စောင့်ကြည့်ရန် လူရှာပါ", + "manually_search": "ကိုယ်တိုင် ရှာဖွေရန်", + "skip": "ကျော်", + "reply": "စာပြန်", + "report_user": " %s ကို တိုင်ကြားရန်", + "block_domain": "%s ကို ဘလော့လုပ်ရန်", + "unblock_domain": "%s ကို ဘလော့ဖြုတ်ရန်", + "settings": "ဆက်တင်များ", + "delete": "ဖျက်" }, "tabs": { - "home": "Home", - "search": "Search", - "notification": "Notification", - "profile": "Profile" + "home": "အိမ်", + "search": "ရှာဖွေရန်", + "notification": "သတိပေးချက်", + "profile": "ကိုယ်ရေးမှတ်တမ်း" }, "keyboard": { "common": { - "switch_to_tab": "Switch to %s", - "compose_new_post": "Compose New Post", - "show_favorites": "Show Favorites", - "open_settings": "Open Settings" + "switch_to_tab": "%s သို့ ပြောင်းရန်", + "compose_new_post": "ပို့စ်အသစ် ရေးဖွဲ့", + "show_favorites": "အကြိုက်ဆုံးများ ပြရန်", + "open_settings": "ဆက်တင်ကို ဖွင့်ရန်" }, "timeline": { - "previous_status": "Previous Post", - "next_status": "Next Post", - "open_status": "Open Post", - "open_author_profile": "Open Author's Profile", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", - "toggle_reblog": "Toggle Reblog on Post", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", - "preview_image": "Preview Image" + "previous_status": "ယခင်ပို့စ်", + "next_status": "နောက်ပို့စ်", + "open_status": "ပို့စ်ဖွင့်ရန်", + "open_author_profile": "စာရေးသူ၏ ပရိုဖိုင်ကို ဖွင့်ပါ", + "open_reblogger_profile": "ပြန်တင်သူ၏ ပရိုဖိုင်ကို ဖွင့်ပါ", + "reply_status": "ပို့စ်ကို စာပြန်", + "toggle_reblog": "ပို့စ်ကိုပြန်တင်ခွင့်ပေးခြင်းကို ဖွင့်၊ပိတ် လုပ်ပါ", + "toggle_favorite": "အကြိုက်ဆုံးလုပ်ခွင့်ပေးခြင်းကို ဖွင့်၊ပိတ် လုပ်ပါ", + "toggle_content_warning": "အကြောင်းအရာသတိပေးချက်ကို ဖွင့်၊ပိတ် လုပ်ပါ", + "preview_image": "ဓာတ်ပုံကို ကြိုကြည့်" }, "segmented_control": { - "previous_section": "Previous Section", - "next_section": "Next Section" + "previous_section": "ယခင်အပိုင်း", + "next_section": "နောက်အပိုင်း" } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", - "show_post": "Show Post", - "show_user_profile": "Show user profile", - "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", + "user_reblogged": "%s ကို ပြန်တင်", + "user_replied_to": "%s ထံ စာပြန်", + "show_post": "ပို့စ်ကို ပြသ", + "show_user_profile": "အသုံးပြုသူ၏ ပရိုဖိုင်ကို ပြရန်", + "content_warning": "အကြောင်းအရာသတိပေးချက်", + "sensitive_content": "ထိလွယ်ရှလွယ် အကြောင်းအရာ", + "media_content_warning": "ဖော်ထုတ်ရန် မည်သည့်နေရာမဆို နှိပ်ပါ", + "tap_to_reveal": "ဖော်ထုတ်ရန် နှိပ်ပါ", "poll": { - "vote": "Vote", - "closed": "Closed" + "vote": "မဲပေး", + "closed": "ပိတ်သွားပြီ" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "လင့်ခ်: %s", + "hashtag": "ဟက်ရှ်တက်ခ်: %s", + "mention": "ပရိုဖိုင် ပြသ: %s", + "email": "အီးမေးလ်လိပ်စာ: %s" }, "actions": { - "reply": "Reply", - "reblog": "Reblog", - "unreblog": "Undo reblog", - "favorite": "Favorite", + "reply": "စာပြန်", + "reblog": "ပြန်တင်", + "unreblog": "ပြန်တင်ခြင်းကို ပယ်ဖျက်", + "favorite": "အကြိုက်ဆုံး", "unfavorite": "အကြိုက်ဆုံးမှ ဖယ်ရှားရန်", "menu": "မီနူး", "hide": "ဝှက်ရန်", @@ -249,9 +249,9 @@ "see_more": "See More" }, "label": { - "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "language": "ဘာသာစကား", + "users": "အသုံးပြုသူများ", + "category": "အမျိုးအစား" }, "input": { "search_servers_or_enter_url": "Search communities or enter URL" From b3572d734cbdabbbc00cb34897d6e7e60fbb32c6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 06:27:16 +0100 Subject: [PATCH 066/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index c4b6bbe32..8e6dd7a04 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -245,8 +245,8 @@ "music": "music", "tech": "tech" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "လျှော့ ကြည့်ရန်", + "see_more": "ပိုမိုကြည့်ရှုရန်" }, "label": { "language": "ဘာသာစကား", @@ -254,58 +254,58 @@ "category": "အမျိုးအစား" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "အသိုင်းအဝိုင်းများကို ရှာဖွေ (သို့) URL ကို ဝင်ရောက်" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "finding_servers": "အဆင်သင့်သုံးရသော ဆာဗာများကို ရှာနေသည်...", + "bad_network": "ဒေတာဖွင့်နေစဉ် တစ်ခုခုမှားယွင်းသွားသည်၊ အင်တာနက်ချိတ်ဆက်မှုကို စစ်ဆေးပါ။", + "no_results": "ရလဒ်မရှိပါ" } }, "register": { - "title": "Let’s get you set up on %s", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "title": "သင့်ကို %s တွင် စတင်လိုက်ရအောင်", + "lets_get_you_set_up_on_domain": "သင့်ကို %s တွင် စတင်လိုက်ရအောင်", "input": { "avatar": { - "delete": "Delete" + "delete": "ဖျက်" }, "username": { "placeholder": "username", "duplicate_prompt": "This username is taken." }, "display_name": { - "placeholder": "display name" + "placeholder": "ပြသမည့် အမည်" }, "email": { - "placeholder": "email" + "placeholder": "အီးမေးလ်" }, "password": { - "placeholder": "password", - "require": "Your password needs at least:", - "character_limit": "8 characters", + "placeholder": "စကားဝှက်", + "require": "သင်၏စကားဝှက်သည် အနည်းဆုံးလိုအပ်သည်:", + "character_limit": "အက္ခရာ ၈ လုံး", "accessibility": { - "checked": "checked", - "unchecked": "unchecked" + "checked": "စစ်ဆေးပြီးပြီ", + "unchecked": "မစစ်ဆေးခဲ့ပါ" }, - "hint": "Your password needs at least eight characters" + "hint": "စကားဝှက်သည် အနည်းဆုံး အက္ခရာ ၈ လုံး ရှိရပါမည်။" }, "invite": { - "registration_user_invite_request": "Why do you want to join?" + "registration_user_invite_request": "သင် ဘာကြောင့် ပါဝင်ချင်တာပါလဲ?" } }, "error": { "item": { - "username": "Username", - "email": "Email", - "password": "Password", - "agreement": "Agreement", - "locale": "Locale", - "reason": "Reason" + "username": "အသုံးပြုသူအမည်", + "email": "အီးမေးလ်", + "password": "စကားဝှက်", + "agreement": "သဘောတူညီမှု", + "locale": "ဒေသဆိုင်ရာ", + "reason": "အကြောင်းပြချက်" }, "reason": { - "blocked": "%s contains a disallowed email provider", - "unreachable": "%s does not seem to exist", - "taken": "%s is already in use", + "blocked": "%s တွင် ခွင့်မပြုထားသော အီးမေးလ်ထောက်ပံ့သူပါဝင်နေသည်။", + "unreachable": "%s တည်ရှိပုံ မပေါ်ပါ", + "taken": "%s ကို အသုံးပြုနေသူ ရှိနှင့်ပြီးဖြစ်သည်။", "reserved": "%s is a reserved keyword", "accepted": "%s must be accepted", "blank": "%s is required", From a7caef98719fe10302487029772d6330e6a2732c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 06:27:17 +0100 Subject: [PATCH 067/733] New translations ios-infoPlist.json (Burmese) --- .../StringsConvertor/input/my.lproj/ios-infoPlist.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json index c6db73de0..b56ff5096 100644 --- a/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/my.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" + "NSCameraUsageDescription": "ပို့စ်အခြေအနေအတွက် ပုံရိုက်ရန် အသုံးပြုခဲ့သည်", + "NSPhotoLibraryAddUsageDescription": "ဓာတ်ပုံပြခန်းတွင် ပုံသိမ်းရန် အသုံးပြုခဲ့သည်", + "NewPostShortcutItemTitle": "ပို့စ်အသစ်", + "SearchShortcutItemTitle": "ရှာဖွေရန်" } From 25dc5e600f7f9a5b7c9f43aba2e5880508600d23 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 06:27:18 +0100 Subject: [PATCH 068/733] New translations Intents.stringsdict (Burmese) --- .../Intents/input/my.lproj/Intents.stringsdict | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict index a14f8b9ff..577ffd124 100644 --- a/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/my.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + ‘${content}’ နှင့် ကိုက်ညီသော ရွေးချယ်စရာ %#@count_option@ ခု ရှိသည်။ count_option NSStringFormatSpecTypeKey @@ -13,13 +13,13 @@ NSStringFormatValueTypeKey %ld other - %ld options + ရွေးချယ်စရာ %ld ခု There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + ‘${visibility}’ နှင့် ကိုက်ညီသော ရွေးချယ်စရာ %#@count_option@ ခု ရှိသည်။ count_option NSStringFormatSpecTypeKey @@ -27,7 +27,7 @@ NSStringFormatValueTypeKey %ld other - %ld options + ရွေးချယ်စရာ %ld ခု From 35e307c79bcaecb10653c160eb6247c334b92cf8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 11:21:48 +0100 Subject: [PATCH 069/733] New translations app.json (Dutch) --- .../StringsConvertor/input/nl.lproj/app.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 589c51d2d..6affcf0a3 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -74,8 +74,8 @@ "take_photo": "Maak foto", "save_photo": "Bewaar foto", "copy_photo": "Kopieer foto", - "sign_in": "Log in", - "sign_up": "Create account", + "sign_in": "Inloggen", + "sign_up": "Account aanmaken", "see_more": "Meer", "preview": "Voorvertoning", "share": "Deel", @@ -139,8 +139,8 @@ "meta_entity": { "url": "Link: %s", "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "mention": "Profiel weergeven: %s", + "email": "E-mailadres: %s" }, "actions": { "reply": "Reageren", @@ -187,8 +187,8 @@ "unmute_user": "%s niet langer negeren", "muted": "Genegeerd", "edit_info": "Bewerken", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "Toon reblogs", + "hide_reblogs": "Verberg reblogs" }, "timeline": { "filtered": "Gefilterd", @@ -219,15 +219,15 @@ "log_in": "Log in" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "Welkom terug", + "subtitle": "Log je in op de server waarop je je account hebt aangemaakt.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Voer URL in of zoek naar uw server" } }, "server_picker": { "title": "Kies een server, welke dan ook.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "Kies een server gebaseerd op je regio, interesses, of een algemene server. Je kunt nog steeds chatten met iedereen op Mastodon, ongeacht op welke server je zit.", "button": { "category": { "all": "Alles", @@ -254,7 +254,7 @@ "category": "CATEGORIE" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Zoek naar gemeenschappen of voer URL in" }, "empty_state": { "finding_servers": "Beschikbare servers zoeken...", @@ -264,7 +264,7 @@ }, "register": { "title": "Vertel ons over uzelf.", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Laten we je account instellen op %s", "input": { "avatar": { "delete": "Verwijderen" From ed8687647dd15f37babc90f30e67566d41859aa4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 12:23:57 +0100 Subject: [PATCH 070/733] New translations app.json (Dutch) --- .../StringsConvertor/input/nl.lproj/app.json | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 6affcf0a3..1df7f51aa 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -335,7 +335,7 @@ "confirm_email": { "title": "Nog één ding.", "subtitle": "We hebben een e-mail gestuurd naar %s,\nklik op de link om uw account te bevestigen.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tik op de link in de e-mail die je hebt ontvangen om uw account te verifiëren", "button": { "open_email_app": "Email Openen", "resend": "Verstuur opnieuw" @@ -360,8 +360,8 @@ "published": "Gepubliceerd!", "Publishing": "Bericht publiceren...", "accessibility": { - "logo_label": "Logo Button", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_label": "Logo knop", + "logo_hint": "Tik om naar boven te scrollen en tik nogmaals om terug te keren naar de vorige locatie" } } }, @@ -388,12 +388,12 @@ "attachment_broken": "Deze %s is corrupt en kan niet geüpload worden naar Mastodon.", "description_photo": "Omschrijf de foto voor mensen met een visuele beperking...", "description_video": "Omschrijf de video voor mensen met een visuele beperking...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "load_failed": "Laden mislukt", + "upload_failed": "Uploaden mislukt", + "can_not_recognize_this_media_attachment": "Kan de media in de bijlage niet herkennen", + "attachment_too_large": "Bijlage te groot", + "compressing_state": "Bezig met comprimeren...", + "server_processing_state": "Server is bezig met verwerken..." }, "poll": { "duration_time": "Duur: %s", @@ -404,8 +404,8 @@ "three_days": "3 Dagen", "seven_days": "7 Dagen", "option_number": "Optie %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "the_poll_is_invalid": "De peiling is ongeldig", + "the_poll_has_empty_option": "De peiling heeft een lege optie" }, "content_warning": { "placeholder": "Schrijf hier een nauwkeurige waarschuwing..." @@ -427,8 +427,8 @@ "enable_content_warning": "Inhoudswaarschuwing inschakelen", "disable_content_warning": "Inhoudswaarschuwing Uitschakelen", "post_visibility_menu": "Berichtzichtbaarheidsmenu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Plaats Bericht Opties", + "posting_as": "Plaats bericht als %s" }, "keyboard": { "discard_post": "Bericht Verwijderen", @@ -441,7 +441,7 @@ }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Volgt jou" }, "dashboard": { "posts": "berichten", @@ -455,8 +455,8 @@ "content": "Inhoud" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Geverifieerd op %s", + "long": "Eigendom van deze link is gecontroleerd op %s" } }, "segmented_control": { @@ -484,12 +484,12 @@ "message": "Bevestig om %s te deblokkeren" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Toon reblogs", + "message": "Bevestig om reblogs te tonen" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Verberg reblogs", + "message": "Bevestig om reblogs te verbergen" } }, "accessibility": { @@ -500,16 +500,16 @@ } }, "follower": { - "title": "follower", + "title": "volger", "footer": "Volgers van andere servers worden niet weergegeven." }, "following": { - "title": "following", + "title": "volgend", "footer": "Volgers van andere servers worden niet weergegeven." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Volgers die je kent", + "followed_by_names": "Gevolgd door %s" }, "favorited_by": { "title": "Favorited By" @@ -555,7 +555,7 @@ "posts": "Berichten", "hashtags": "Hashtags", "news": "Nieuws", - "community": "Community", + "community": "Gemeenschap", "for_you": "Voor jou" }, "intro": "Dit zijn de berichten die populair zijn in jouw Mastodon-kringen." @@ -581,10 +581,10 @@ "show_mentions": "Vermeldingen weergeven" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Accepteren", + "accepted": "Geaccepteerd", + "reject": "afwijzen", + "rejected": "Afgewezen" } }, "thread": { @@ -661,11 +661,11 @@ "text_placeholder": "Schrijf of plak aanvullende opmerkingen", "reported": "Gerapporteerd", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", + "step_1_of_4": "Stap 1 van 4", + "whats_wrong_with_this_post": "Wat is er mis met dit bericht?", + "whats_wrong_with_this_account": "Wat is er mis met dit bericht?", + "whats_wrong_with_this_username": "Wat is er mis met %s?", + "select_the_best_match": "Selecteer de beste overeenkomst", "i_dont_like_it": "I don’t like it", "it_is_not_something_you_want_to_see": "It is not something you want to see", "its_spam": "It’s spam", From 49a295be5ad04d878a5ce28b62cf44348ad5a03c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 15:27:21 +0100 Subject: [PATCH 071/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 8e6dd7a04..9f56d4471 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -175,35 +175,35 @@ "following": "စောင့်ကြည့်နေသည်", "request": "တောင်းဆို", "pending": "ဆိုင်းငံ့ထားသည်", - "block": "Block", - "block_user": "Block %s", - "block_domain": "Block %s", - "unblock": "Unblock", - "unblock_user": "Unblock %s", - "blocked": "Blocked", - "mute": "Mute", - "mute_user": "Mute %s", - "unmute": "Unmute", - "unmute_user": "Unmute %s", - "muted": "Muted", - "edit_info": "Edit Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "block": "ဘလော့လုပ်ရန်", + "block_user": "%s ကို ဘလော့လုပ်ရန်", + "block_domain": "%s ကို ဘလော့လုပ်ရန်", + "unblock": "ဘလော့ဖြုတ်ရန်", + "unblock_user": "%s ကို ဘလော့ဖြုတ်ရန်", + "blocked": "ဘလော့ထားသည်", + "mute": "ပိတ်ထားရန်", + "mute_user": "%s ကို ပိတ်ထားရန်", + "unmute": "ပြန်ဖွင့်ရန်", + "unmute_user": "%s ကို ပြန်ဖွင့်ရန်", + "muted": "ပိတ်ထားဆဲ", + "edit_info": "အချက်အလက်တည်းဖြတ်", + "show_reblogs": "ပြန်တင်ထားတာတွေ ပြရန်", + "hide_reblogs": "ပြန်တင်ထားတာတွေ ဖျောက်ရန်" }, "timeline": { - "filtered": "Filtered", + "filtered": "စစ်ထုတ်ထားသည်", "timestamp": { - "now": "Now" + "now": "ယခု" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", - "show_more_replies": "Show more replies" + "load_missing_posts": "ပျောက်နေသော ပို့စ်များကို လုဒ်ပါ", + "loading_missing_posts": "ပျောက်နေသော ပို့စ်များကို လုဒ်ပါ...", + "show_more_replies": "ပြန်စာများထပ်ပြပါ" }, "header": { - "no_status_found": "No Post Found", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", + "no_status_found": "ပို့စ်ရှာမတွေ့ပါ", + "blocking_warning": "ဒီအသုံးပြုသူ၏ ပရိုဖိုင်ကို ဘလော့မဖြုတ်မချင်း ကြည့်၍မရပါ၊ သင်၏ ပရိုဖိုင်သည် ထိုသူတို့ထံ ဤကဲ့သို့ ပေါ်နေပါမည်။", + "user_blocking_warning": "%s၏ ပရိုဖိုင်ကို ဘလော့မဖြုတ်မချင်း ကြည့်၍မရပါ၊ သင်၏ ပရိုဖိုင်သည် ထိုသူ့ထံ ဤကဲ့သို့ ပေါ်နေပါမည်။", "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", "suspended_warning": "This user has been suspended.", @@ -234,16 +234,16 @@ "all_accessiblity_description": "Category: All", "academia": "academia", "activism": "activism", - "food": "food", + "food": "အစားအစာ", "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", + "games": "ဂိမ်း", + "general": "အထွေထွေ", + "journalism": "သတင်းစာပညာ", "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "regional": "နယ်မြေဆိုင်ရာ", + "art": "အနုပညာ", + "music": "ဂီတ", + "tech": "နည်းပညာ" }, "see_less": "လျှော့ ကြည့်ရန်", "see_more": "ပိုမိုကြည့်ရှုရန်" @@ -270,7 +270,7 @@ "delete": "ဖျက်" }, "username": { - "placeholder": "username", + "placeholder": "အသုံးပြုသူအမည်", "duplicate_prompt": "This username is taken." }, "display_name": { From 70cb9bf0e855ceb4f0f4b09eefdfa20b98bd12c4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 16:22:26 +0100 Subject: [PATCH 072/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 440 +++++++++--------- 1 file changed, 220 insertions(+), 220 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index fec3197be..69cf3416d 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -2,26 +2,26 @@ "common": { "alerts": { "common": { - "please_try_again": "Please try again.", - "please_try_again_later": "Please try again later." + "please_try_again": "Ceisiwch eto.", + "please_try_again_later": "Ceisiwch eto nes ymlaen." }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "Gwall Ymgofrestru" }, "server_error": { - "title": "Server Error" + "title": "Gwall Gweinydd" }, "vote_failure": { - "title": "Vote Failure", - "poll_ended": "The poll has ended" + "title": "Gwall Pleidleisio", + "poll_ended": "Mae'r pôl wedi dod i ben" }, "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." + "title": "Dileu Drafft", + "message": "Cadarnhau i ddileu post drafft." }, "publish_post_failure": { - "title": "Publish Failure", - "message": "Failed to publish the post.\nPlease check your internet connection.", + "title": "Gwall Cyhoeddi", + "message": "Gwall wrth gyhoeddi'r tŵt.\nGwiriwch eich cysylltiad i'r rhyngrhwyd.", "attachments_message": { "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", "more_than_one_video": "Cannot attach more than one video." @@ -32,9 +32,9 @@ "message": "Cannot edit profile. Please try again." }, "sign_out": { - "title": "Sign Out", + "title": "Allgofnodi", "message": "Are you sure you want to sign out?", - "confirm": "Sign Out" + "confirm": "Allgofnodi" }, "block_domain": { "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", @@ -45,74 +45,74 @@ "message": "Please enable the photo library access permission to save the photo." }, "delete_post": { - "title": "Delete Post", + "title": "Dileu Tŵt", "message": "Are you sure you want to delete this post?" }, "clean_cache": { - "title": "Clean Cache", - "message": "Successfully cleaned %s cache." + "title": "Clirio storfa", + "message": "Cliriwyd storfa %s yn llwyddiannus." } }, "controls": { "actions": { - "back": "Back", - "next": "Next", - "previous": "Previous", - "open": "Open", - "add": "Add", - "remove": "Remove", - "edit": "Edit", - "save": "Save", - "ok": "OK", - "done": "Done", - "confirm": "Confirm", - "continue": "Continue", - "compose": "Compose", - "cancel": "Cancel", - "discard": "Discard", - "try_again": "Try Again", - "take_photo": "Take Photo", - "save_photo": "Save Photo", - "copy_photo": "Copy Photo", - "sign_in": "Log in", - "sign_up": "Create account", - "see_more": "See More", - "preview": "Preview", - "share": "Share", - "share_user": "Share %s", - "share_post": "Share Post", - "open_in_safari": "Open in Safari", - "open_in_browser": "Open in Browser", - "find_people": "Find people to follow", - "manually_search": "Manually search instead", - "skip": "Skip", - "reply": "Reply", - "report_user": "Report %s", - "block_domain": "Block %s", + "back": "Nôl", + "next": "Ymlaen", + "previous": "Blaenorol", + "open": "Agor", + "add": "Ychwanegu", + "remove": "Dileu", + "edit": "Golygu", + "save": "Cadw", + "ok": "Iawn", + "done": "Iawn", + "confirm": "Cadarnhau", + "continue": "Parhau", + "compose": "Creu", + "cancel": "Canslo", + "discard": "Diddymu", + "try_again": "Ceisio eto", + "take_photo": "Tynnu Llun", + "save_photo": "Cadw Llun", + "copy_photo": "Copïo Llun", + "sign_in": "Mewngofnodi", + "sign_up": "Creu cyfrif", + "see_more": "Gweld Mwy", + "preview": "Rhagolwg", + "share": "Rhannu", + "share_user": "Rhannu %s", + "share_post": "Rhannu Tŵt", + "open_in_safari": "Agor yn Safari", + "open_in_browser": "Agor yn y Porwr", + "find_people": "Dilyn pobl newydd", + "manually_search": "Chwilio yn fanwl", + "skip": "Anwybyddu", + "reply": "Ymateb", + "report_user": "Riportio %s", + "block_domain": "Blocio %s", "unblock_domain": "Unblock %s", - "settings": "Settings", - "delete": "Delete" + "settings": "Gosodiadau", + "delete": "Dileu" }, "tabs": { - "home": "Home", - "search": "Search", - "notification": "Notification", - "profile": "Profile" + "home": "Hafan", + "search": "Chwilio", + "notification": "Hysbysiad", + "profile": "Proffil" }, "keyboard": { "common": { - "switch_to_tab": "Switch to %s", - "compose_new_post": "Compose New Post", - "show_favorites": "Show Favorites", - "open_settings": "Open Settings" + "switch_to_tab": "Newid i %s", + "compose_new_post": "Creu Tŵt Newydd", + "show_favorites": "Dangos Ffefrynnau", + "open_settings": "Agor Gosodiadau" }, "timeline": { - "previous_status": "Previous Post", - "next_status": "Next Post", - "open_status": "Open Post", - "open_author_profile": "Open Author's Profile", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", + "previous_status": "Tŵt Blaenorol", + "next_status": "Tŵt Nesaf", + "open_status": "Agor Tŵt", + "open_author_profile": "Agor Proffil yr Awdur", + "open_reblogger_profile": "Agor Proffil yr Ailflogwr", + "reply_status": "Ymateb i Tŵt", "toggle_reblog": "Toggle Reblog on Post", "toggle_favorite": "Toggle Favorite on Post", "toggle_content_warning": "Toggle Content Warning", @@ -120,88 +120,88 @@ }, "segmented_control": { "previous_section": "Previous Section", - "next_section": "Next Section" + "next_section": "Adran Nesaf" } }, "status": { "user_reblogged": "%s reblogged", "user_replied_to": "Replied to %s", - "show_post": "Show Post", - "show_user_profile": "Show user profile", - "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", + "show_post": "Dangos Tŵt", + "show_user_profile": "Dangos proffil y defnyddiwr", + "content_warning": "Rhybudd Cynnwys", + "sensitive_content": "Cynnwys Sensitif", + "media_content_warning": "Tapiwch unrhywle i weld", + "tap_to_reveal": "Tapiwch i weld", "poll": { - "vote": "Vote", - "closed": "Closed" + "vote": "Pleidleisio", + "closed": "Wedi cau" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Dolen: %s", + "hashtag": "Hashnod: %s", + "mention": "Dangos Proffil: %s", + "email": "Cyfeiriad e-bost: %s" }, "actions": { - "reply": "Reply", + "reply": "Ymateb", "reblog": "Hybwch", - "unreblog": "Undo reblog", - "favorite": "Favorite", - "unfavorite": "Unfavorite", - "menu": "Menu", - "hide": "Hide", - "show_image": "Show image", - "show_gif": "Show GIF", - "show_video_player": "Show video player", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "unreblog": "Dadwneud ailfloggiad", + "favorite": "Ffefrynnu", + "unfavorite": "Dad-ffefrynnu", + "menu": "Dewislen", + "hide": "Cuddio", + "show_image": "Dangos llun", + "show_gif": "Dangos GIF", + "show_video_player": "Dangos chwaraewr fideo", + "tap_then_hold_to_show_menu": "Tapiwch a gwasgu i gael y ddewislen" }, "tag": { "url": "URL", - "mention": "Mention", - "link": "Link", - "hashtag": "Hashtag", - "email": "Email", + "mention": "Sôn", + "link": "Dolen", + "hashtag": "Hashnod", + "email": "E-bost", "emoji": "Emoji" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", + "unlisted": "Gall pawb weld y post hwn ond nid yn y ffrwd cyhoeddus.", "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." } }, "friendship": { - "follow": "Follow", - "following": "Following", - "request": "Request", - "pending": "Pending", - "block": "Block", - "block_user": "Block %s", - "block_domain": "Block %s", - "unblock": "Unblock", - "unblock_user": "Unblock %s", - "blocked": "Blocked", + "follow": "Dilyn", + "following": "Yn dilyn", + "request": "Gwneud cais", + "pending": "Yn aros", + "block": "Blocio", + "block_user": "Blocio %s", + "block_domain": "Blocio %s", + "unblock": "Dadflocio", + "unblock_user": "Dadflocio %s", + "blocked": "Wedi blocio", "mute": "Mute", "mute_user": "Mute %s", "unmute": "Unmute", "unmute_user": "Unmute %s", "muted": "Muted", - "edit_info": "Edit Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "edit_info": "Golygu", + "show_reblogs": "Dangos Ailfloggiau", + "hide_reblogs": "Cuddio Ailfloggiau" }, "timeline": { - "filtered": "Filtered", + "filtered": "Wedi'i hidlo", "timestamp": { - "now": "Now" + "now": "Nawr" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", - "show_more_replies": "Show more replies" + "load_missing_posts": "Llwytho postau coll", + "loading_missing_posts": "Wrthi'n llwytho postau coll...", + "show_more_replies": "Dangos mwy o ymatebion" }, "header": { - "no_status_found": "No Post Found", + "no_status_found": "Ni Chanfuwyd Post", "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", @@ -216,10 +216,10 @@ "welcome": { "slogan": "Social networking\nback in your hands.", "get_started": "Get Started", - "log_in": "Log In" + "log_in": "Mewngofnodi" }, "login": { - "title": "Welcome back", + "title": "Croeso nôl", "subtitle": "Log you in on the server you created your account on.", "server_search_field": { "placeholder": "Enter URL or search for your server" @@ -230,11 +230,11 @@ "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", "button": { "category": { - "all": "All", + "all": "Popeth", "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", - "food": "food", + "academia": "academaidd", + "activism": "gweithgarwch", + "food": "bwyd", "furry": "furry", "games": "games", "general": "general", @@ -250,8 +250,8 @@ }, "label": { "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "users": "DEFNYDDWYR", + "category": "CATEGORI" }, "input": { "search_servers_or_enter_url": "Search communities or enter URL" @@ -267,22 +267,22 @@ "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { - "delete": "Delete" + "delete": "Dileu" }, "username": { - "placeholder": "username", - "duplicate_prompt": "This username is taken." + "placeholder": "enw defnyddiwr", + "duplicate_prompt": "Defnyddir yr enw hwn yn barod." }, "display_name": { - "placeholder": "display name" + "placeholder": "enw arddangos" }, "email": { - "placeholder": "email" + "placeholder": "e-bost" }, "password": { - "placeholder": "password", - "require": "Your password needs at least:", - "character_limit": "8 characters", + "placeholder": "cyfrinair", + "require": "Mae angen i'ch cyfrinair gael o leiaf:", + "character_limit": "8 nod", "accessibility": { "checked": "checked", "unchecked": "unchecked" @@ -290,17 +290,17 @@ "hint": "Your password needs at least eight characters" }, "invite": { - "registration_user_invite_request": "Why do you want to join?" + "registration_user_invite_request": "Pam ydych chi eisiau ymuno?" } }, "error": { "item": { - "username": "Username", - "email": "Email", - "password": "Password", - "agreement": "Agreement", - "locale": "Locale", - "reason": "Reason" + "username": "Enw defnyddiwr", + "email": "E-bost", + "password": "Cyfrinair", + "agreement": "Cytundeb", + "locale": "Lleoliad", + "reason": "Rheswm" }, "reason": { "blocked": "%s contains a disallowed email provider", @@ -323,44 +323,44 @@ } }, "server_rules": { - "title": "Some ground rules.", + "title": "Rhai rheolau sylfaenol.", "subtitle": "These are set and enforced by the %s moderators.", "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "terms_of_service": "telerau gwasanaeth", + "privacy_policy": "polisi preifatrwydd", "button": { - "confirm": "I Agree" + "confirm": "Rwy'n cytuno" } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "title": "Un peth olaf.", + "subtitle": "Tapiwch ar y ddolen yn eich e-bost i ddilysu eich cyfrif.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tapiwch ar y ddolen yn eich e-bost i ddilysu eich cyfrif", "button": { - "open_email_app": "Open Email App", - "resend": "Resend" + "open_email_app": "Agor ap e-byst", + "resend": "Ailanfon" }, "dont_receive_email": { - "title": "Check your email", + "title": "Gwiriwch eich e-byst", "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "resend_email": "Ailanfon E-bost" }, "open_email_app": { - "title": "Check your inbox.", + "title": "Gwiriwch eich blwch derbyn.", "description": "We just sent you an email. Check your junk folder if you haven’t.", "mail": "Mail", "open_email_client": "Open Email Client" } }, "home_timeline": { - "title": "Home", + "title": "Hafan", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "All-lein", + "new_posts": "Gweld tŵts newydd", + "published": "Wedi cyhoeddi!", + "Publishing": "Wrthi'n cyhoeddi...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Botwm Logo", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -371,11 +371,11 @@ }, "compose": { "title": { - "new_post": "New Post", + "new_post": "Tŵt Newydd", "new_reply": "New Reply" }, "media_selection": { - "camera": "Take Photo", + "camera": "Tynnu Llun", "photo_library": "Photo Library", "browse": "Browse" }, @@ -398,11 +398,11 @@ "poll": { "duration_time": "Duration: %s", "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", - "three_days": "3 Days", - "seven_days": "7 Days", + "one_hour": "1 awr", + "six_hours": "6 awr", + "one_day": "1 diwrnod", + "three_days": "3 diwrnod", + "seven_days": "7 diwrnod", "option_number": "Option %ld", "the_poll_is_invalid": "The poll is invalid", "the_poll_has_empty_option": "The poll has empty option" @@ -411,9 +411,9 @@ "placeholder": "Write an accurate warning here..." }, "visibility": { - "public": "Public", + "public": "Cyhoeddus", "unlisted": "Unlisted", - "private": "Followers only", + "private": "Dilynwyr yn unig", "direct": "Only people I mention" }, "auto_complete": { @@ -445,14 +445,14 @@ }, "dashboard": { "posts": "postiadau", - "following": "following", - "followers": "followers" + "following": "yn dilyn", + "followers": "dilynwyr" }, "fields": { - "add_row": "Add Row", + "add_row": "Ychwanegu Rhes", "placeholder": { "label": "Label", - "content": "Content" + "content": "Cynnwys" }, "verified": { "short": "Verified on %s", @@ -461,10 +461,10 @@ }, "segmented_control": { "posts": "Postiadau", - "replies": "Replies", + "replies": "Ymatebion", "posts_and_replies": "Postiadau ac Atebion", - "media": "Media", - "about": "About" + "media": "Cyfryngau", + "about": "Ynghylch" }, "relationship_action_alert": { "confirm_mute_user": { @@ -493,10 +493,10 @@ } }, "accessibility": { - "show_avatar_image": "Show avatar image", - "edit_avatar_image": "Edit avatar image", - "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "show_avatar_image": "Dangos afatar", + "edit_avatar_image": "Golygu afatar", + "show_banner_image": "Dangos baner", + "double_tap_to_open_the_list": "Tapiwch dwywaith i agor y restr" } }, "follower": { @@ -526,46 +526,46 @@ "recommend": { "button_text": "See All", "hash_tag": { - "title": "Trending on Mastodon", - "description": "Hashtags that are getting quite a bit of attention", - "people_talking": "%s people are talking" + "title": "Pynciau Llosg ar Mastodon", + "description": "Dyma'r hashnodau sy'n derbyn tipyn o sylw", + "people_talking": "%s person yn trafod" }, "accounts": { "title": "Accounts you might like", "description": "You may like to follow these accounts", - "follow": "Follow" + "follow": "Dilyn" } }, "searching": { "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", + "all": "Popeth", + "people": "Pobl", + "hashtags": "Hashnodau", "posts": "Postiadau" }, "empty_state": { - "no_results": "No results" + "no_results": "Dim canlyniadau" }, - "recent_search": "Recent searches", - "clear": "Clear" + "recent_search": "Chwiliadau diweddar", + "clear": "Clirio" } }, "discovery": { "tabs": { "posts": "Postiadau", - "hashtags": "Hashtags", - "news": "News", - "community": "Community", - "for_you": "For You" + "hashtags": "Hashnodau", + "news": "Newyddion", + "community": "Cymuned", + "for_you": "I Ti" }, "intro": "These are the posts gaining traction in your corner of Mastodon." }, "favorite": { - "title": "Your Favorites" + "title": "Eich Ffefrynnau" }, "notification": { "title": { - "Everything": "Everything", + "Everything": "Popeth", "Mentions": "Mentions" }, "notification_description": { @@ -592,30 +592,30 @@ "title": "Post from %s" }, "settings": { - "title": "Settings", + "title": "Gosodiadau", "section": { "appearance": { - "title": "Appearance", - "automatic": "Automatic", - "light": "Always Light", - "dark": "Always Dark" + "title": "Gwedd", + "automatic": "Awtomatig", + "light": "Golau", + "dark": "Tywyll" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "Gwedd", + "use_system": "Dull y System", + "really_dark": "Tywyll Iawn", + "sorta_dark": "Eitha' Tywyll", + "light": "Golau" }, "notifications": { - "title": "Notifications", + "title": "Hysbysiadau", "favorites": "Favorites my post", "follows": "Follows me", "boosts": "Reblogs my post", "mentions": "Mentions me", "trigger": { - "anyone": "anyone", - "follower": "a follower", + "anyone": "unrhyw un", + "follower": "dilynwr", "follow": "anyone I follow", "noone": "no one", "title": "Notify me when" @@ -661,7 +661,7 @@ "text_placeholder": "Type or paste additional comments", "reported": "REPORTED", "step_one": { - "step_1_of_4": "Step 1 of 4", + "step_1_of_4": "Cam 1 o 4", "whats_wrong_with_this_post": "What's wrong with this post?", "whats_wrong_with_this_account": "What's wrong with this account?", "whats_wrong_with_this_username": "What's wrong with %s?", @@ -670,53 +670,53 @@ "it_is_not_something_you_want_to_see": "It is not something you want to see", "its_spam": "It’s spam", "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", + "it_violates_server_rules": "Mae'n torri rheolau'r gweinydd", "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", + "its_something_else": "Mae'n rhywbeth arall", "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" }, "step_two": { - "step_2_of_4": "Step 2 of 4", + "step_2_of_4": "Cam 2 o 4", "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", - "i_just_don’t_like_it": "I just don’t like it" + "select_all_that_apply": "Dewiswch bob un sy'n berthnasol", + "i_just_don’t_like_it": "Dydw i ddim yn ei hoffi" }, "step_three": { - "step_3_of_4": "Step 3 of 4", + "step_3_of_4": "Cam 3 o 4", "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "select_all_that_apply": "Dewiswch bob un sy'n berthnasol" }, "step_four": { - "step_4_of_4": "Step 4 of 4", + "step_4_of_4": "Cam 4 o 4", "is_there_anything_else_we_should_know": "Is there anything else we should know?" }, "step_final": { "dont_want_to_see_this": "Don’t want to see this?", "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", - "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", + "unfollow": "Dad-ddilyn", + "unfollowed": "Dad-ddilynwyd", + "unfollow_user": "Dad-ddilyn %s", "mute_user": "Mute %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", + "block_user": "Blocio %s", "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Cau Rhagolwg", + "show_next": "Dangos Nesaf", + "show_previous": "Dangos Blaenorol" } }, "account_list": { "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", "dismiss_account_switcher": "Dismiss Account Switcher", - "add_account": "Add Account" + "add_account": "Ychwanegu Cyfrif" }, "wizard": { - "new_in_mastodon": "New in Mastodon", + "new_in_mastodon": "Newydd i Mastodon", "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", "accessibility_hint": "Double tap to dismiss this wizard" }, From 6ed3cbca09291a36003bc953d0a37a626e45a119 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 16:22:27 +0100 Subject: [PATCH 073/733] New translations Localizable.stringsdict (Welsh) --- .../input/cy.lproj/Localizable.stringsdict | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict index 9e4c09959..ee167673e 100644 --- a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict @@ -61,17 +61,17 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld nod one - 1 character + %ld nod two - %ld characters + %ld nod few - %ld characters + %ld nod many - %ld characters + %ld nod other - %ld characters + %ld nod a11y.plural.count.characters_left @@ -85,17 +85,17 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld nod one - 1 character + %ld nod two - %ld characters + %ld nod few - %ld characters + %ld nod many - %ld characters + %ld nod other - %ld characters + %ld nod plural.count.followed_by_and_mutual @@ -156,7 +156,7 @@ one post two - postiau + post few posts many @@ -176,17 +176,17 @@ NSStringFormatValueTypeKey ld zero - %ld media + %ld cyfrwng one - 1 media + %ld cyfrwng two - %ld media + %ld gyfrwng few - %ld media + %ld cyfrwng many - %ld media + %ld cyfrwng other - %ld media + %ld cyfrwng plural.count.post From 2f28fadbd1cfef2633694a9b5de8e15855d75d79 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 16:22:28 +0100 Subject: [PATCH 074/733] New translations Intents.stringsdict (Welsh) --- .../StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict index f273a551d..1673f7287 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict @@ -47,7 +47,7 @@ many %ld options other - %ld options + %ld opsiwn From 0fe40fd8e7e343930032705c033a6cb8290c3417 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 16:22:30 +0100 Subject: [PATCH 075/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 9f56d4471..1c3242165 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -203,37 +203,37 @@ "header": { "no_status_found": "ပို့စ်ရှာမတွေ့ပါ", "blocking_warning": "ဒီအသုံးပြုသူ၏ ပရိုဖိုင်ကို ဘလော့မဖြုတ်မချင်း ကြည့်၍မရပါ၊ သင်၏ ပရိုဖိုင်သည် ထိုသူတို့ထံ ဤကဲ့သို့ ပေါ်နေပါမည်။", - "user_blocking_warning": "%s၏ ပရိုဖိုင်ကို ဘလော့မဖြုတ်မချင်း ကြည့်၍မရပါ၊ သင်၏ ပရိုဖိုင်သည် ထိုသူ့ထံ ဤကဲ့သို့ ပေါ်နေပါမည်။", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "user_blocking_warning": "%s ၏ ပရိုဖိုင်ကို ဘလော့မဖြုတ်မချင်း ကြည့်၍မရပါ၊ သင်၏ ပရိုဖိုင်သည် ထိုသူ့ထံ ဤကဲ့သို့ ပေါ်နေပါမည်။", + "blocked_warning": "ဤပုဂ္ဂိုလ်မှ သင့်ကို ဘလော့မဖြုတ်မချင်း သူ၏ ပရိုဖိုင်သည် သင် ကြည့်၍မရပါ။", + "user_blocked_warning": "%s မှ သင့်ကို ဘလော့မဖြုတ်မချင်း သူ၏ ပရိုဖိုင်သည် သင် ကြည့်၍မရပါ။", + "suspended_warning": "ဤအသုံးပြုသူသည် ဆိုင်းငံ့ခံထားရသည်။", + "user_suspended_warning": "%s ၏အကောင့်သည် ဆိုင်းငံ့ခံထားရသည်။" } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", - "log_in": "Log In" + "slogan": "လူမှုကွန်ယက်ကို သင်၏လက်ထဲသို့ ပြန်လည်ထည့်ပေးလိုက်ပြီ။", + "get_started": "စတင်ရန်", + "log_in": "လော့ခ်အင်ဝင်ရန်" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "ပြန်လည်ကြိုဆိုပါသည်", + "subtitle": "သင်၏အကောင့်ဖွင့်ခဲ့သော ဆာဗာပေါ်တွင် လော့ခ်အင်ဝင်ရောက်ပါ", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "URL ကို ထည့်သွင်းပါ (သို့) သင်၏ ဆာဗာကို ရှာပါ" } }, "server_picker": { - "title": "Mastodon is made of users in different servers.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "title": "Mastodon ကို အသိုင်းအဝန်းပေါင်းစုံမှ အသုံးပြုသူများဖြင့် ဖွဲ့စည်းထားသည်။", + "subtitle": "သင်၏ ဒေသ၊ စိတ်ဝင်စားမှု အပေါ်အခြေခံသော ဆာဗာတစ်ခု ရွေးချယ်ပါ၊ မည်သည့်ဆာဗာကို ရွေးချယ်ထားစေကာမူ အခြားအသုံးပြုသူများနှင့် ပုံမှန်အတိုင်း ဆက်သွယ်နိုင်သည်။", "button": { "category": { - "all": "All", - "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", + "all": "အားလုံး", + "all_accessiblity_description": "အမျိုးအစား - အားလုံး", + "academia": "ပညာရှင်", + "activism": "တက်ကြွလှုပ်ရှားမှု", "food": "အစားအစာ", "furry": "furry", "games": "ဂိမ်း", @@ -271,7 +271,7 @@ }, "username": { "placeholder": "အသုံးပြုသူအမည်", - "duplicate_prompt": "This username is taken." + "duplicate_prompt": "ဤအသုံးပြုသူအမည်သည် ရှိနှင့်ပြီးဖြစ်သည်။" }, "display_name": { "placeholder": "ပြသမည့် အမည်" @@ -436,7 +436,7 @@ "toggle_poll": "Toggle Poll", "toggle_content_warning": "Toggle Content Warning", "append_attachment_entry": "Add Attachment - %s", - "select_visibility_entry": "Select Visibility - %s" + "select_visibility_entry": "မြင်နိုင်စွမ်း ရွေးချယ်ရန် - %s" } }, "profile": { From 3a1c5ba93e5b9f04c608ff9b00c7c4184244c612 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:25 +0100 Subject: [PATCH 076/733] New translations app.json (Basque) --- .../StringsConvertor/input/eu.lproj/app.json | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 3da0d6a00..c52ffdbbf 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -74,8 +74,8 @@ "take_photo": "Atera argazkia", "save_photo": "Gorde argazkia", "copy_photo": "Kopiatu argazkia", - "sign_in": "Log in", - "sign_up": "Create account", + "sign_in": "Hasi saioa", + "sign_up": "Sortu kontua", "see_more": "Ikusi gehiago", "preview": "Aurrebista", "share": "Partekatu", @@ -129,7 +129,7 @@ "show_post": "Erakutsi bidalketa", "show_user_profile": "Erakutsi erabiltzailearen profila", "content_warning": "Edukiaren abisua", - "sensitive_content": "Sensitive Content", + "sensitive_content": "Eduki hunkigarria", "media_content_warning": "Ukitu edonon bistaratzeko", "tap_to_reveal": "Sakatu erakusteko", "poll": { @@ -137,10 +137,10 @@ "closed": "Itxita" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Lotura: %s", + "hashtag": "Traolak: %s", + "mention": "Erakutsi Profila: %s", + "email": "E-posta helbidea: %s" }, "actions": { "reply": "Erantzun", @@ -187,8 +187,8 @@ "unmute_user": "Desmututu %s", "muted": "Mutututa", "edit_info": "Editatu informazioa", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "Ikusi bultzadak", + "hide_reblogs": "Ezkutatu bultzadak" }, "timeline": { "filtered": "Iragazita", @@ -219,7 +219,7 @@ "log_in": "Hasi saioa" }, "login": { - "title": "Welcome back", + "title": "Ongi etorri berriro ere", "subtitle": "Log you in on the server you created your account on.", "server_search_field": { "placeholder": "Enter URL or search for your server" @@ -264,7 +264,7 @@ }, "register": { "title": "Hitz egin iezaguzu zuri buruz.", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "%s zerbitzariko kontua prestatuko dizugu", "input": { "avatar": { "delete": "Ezabatu" @@ -335,7 +335,7 @@ "confirm_email": { "title": "Eta azkenik...", "subtitle": "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko", "button": { "open_email_app": "Ireki eposta aplikazioa", "resend": "Berbidali" @@ -360,7 +360,7 @@ "published": "Argitaratua!", "Publishing": "Bidalketa argitaratzen...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Logo botoia", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -389,10 +389,10 @@ "description_photo": "Deskribatu argazkia ikusmen arazoak dituztenentzat...", "description_video": "Deskribatu bideoa ikusmen arazoak dituztenentzat...", "load_failed": "Load Failed", - "upload_failed": "Upload Failed", + "upload_failed": "Kargatzeak huts egin du", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", + "attachment_too_large": "Eranskina handiegia da", + "compressing_state": "Konprimatzen...", "server_processing_state": "Server Processing..." }, "poll": { @@ -404,7 +404,7 @@ "three_days": "3 egun", "seven_days": "7 egun", "option_number": "%ld aukera", - "the_poll_is_invalid": "The poll is invalid", + "the_poll_is_invalid": "Inkesta ez da balekoa", "the_poll_has_empty_option": "The poll has empty option" }, "content_warning": { @@ -427,7 +427,7 @@ "enable_content_warning": "Gaitu edukiaren abisua", "disable_content_warning": "Desgaitu edukiaren abisua", "post_visibility_menu": "Bidalketaren ikusgaitasunaren menua", - "post_options": "Post Options", + "post_options": "Bildalketaren aukerak", "posting_as": "Posting as %s" }, "keyboard": { @@ -441,7 +441,7 @@ }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Jarraitzen zaitu" }, "dashboard": { "posts": "bidalketa", @@ -456,7 +456,7 @@ }, "verified": { "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "long": "Esteka honen jabetzaren egiaztaketa data: %s" } }, "segmented_control": { @@ -484,12 +484,12 @@ "message": "Berretsi %s desblokeatzea" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Ikusi bultzadak", + "message": "Berretsi birbidalketak ikustea" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Ezkutatu bultzadak", + "message": "Berretsi birbidalketak ezkutatzea" } }, "accessibility": { @@ -500,11 +500,11 @@ } }, "follower": { - "title": "follower", + "title": "jarraitzaile", "footer": "Beste zerbitzarietako jarraitzaileak ez dira bistaratzen." }, "following": { - "title": "following", + "title": "jarraitzen", "footer": "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen." }, "familiarFollowers": { @@ -555,10 +555,10 @@ "posts": "Argitalpenak", "hashtags": "Traolak", "news": "Albisteak", - "community": "Community", + "community": "Komunitatea", "for_you": "Zuretzat" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Hauek dira zure Mastodon txokoan beraien lekua hartzen ari diren argitalpenak." }, "favorite": { "title": "Zure gogokoak" @@ -581,10 +581,10 @@ "show_mentions": "Erakutsi aipamenak" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Onartu", + "accepted": "Onartuta", + "reject": "ukatu", + "rejected": "Ukatua" } }, "thread": { @@ -661,46 +661,46 @@ "text_placeholder": "Idatzi edo itsatsi iruzkin gehigarriak", "reported": "SALATUA", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "step_1_of_4": "1. urratsa 4tik", + "whats_wrong_with_this_post": "Zer du txarra argitalpen honek?", + "whats_wrong_with_this_account": "Zer du txarra kontu honek?", + "whats_wrong_with_this_username": "Zer du txarra %s?", + "select_the_best_match": "Aukeratu egokiena", + "i_dont_like_it": "Ez dut gustukoa", + "it_is_not_something_you_want_to_see": "Ikusi nahi ez dudan zerbait da", + "its_spam": "Spama da", + "malicious_links_fake_engagement_or_repetetive_replies": "Esteka maltzurrak, gezurrezko elkarrekintzak edo erantzun errepikakorrak", + "it_violates_server_rules": "Zerbitzariaren arauak hausten ditu", + "you_are_aware_that_it_breaks_specific_rules": "Arau zehatzak urratzen dituela badakizu", + "its_something_else": "Beste zerbait da", + "the_issue_does_not_fit_into_other_categories": "Arazoa ezin da beste kategorietan sailkatu" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", + "step_2_of_4": "2. urratsa 4tik", + "which_rules_are_being_violated": "Ze arau hautsi ditu?", + "select_all_that_apply": "Hautatu dagozkion guztiak", "i_just_don’t_like_it": "I just don’t like it" }, "step_three": { - "step_3_of_4": "Step 3 of 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "step_3_of_4": "3. urratsa 4tik", + "are_there_any_posts_that_back_up_this_report": "Salaketa hau babesten duen bidalketarik badago?", + "select_all_that_apply": "Hautatu dagozkion guztiak" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "4. urratsa 4tik", + "is_there_anything_else_we_should_know": "Beste zerbait jakin beharko genuke?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", + "dont_want_to_see_this": "Ez duzu hau ikusi nahi?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Mastodonen gustuko ez duzun zerbait ikusten duzunean, zure esperientziatik atera dezakezu pertsona hori.", + "unfollow": "Utzi jarraitzeari", "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "unfollow_user": "%s jarraitzeari utzi", + "mute_user": "Mututu %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Ez dituzu bere bidalketa eta birbidalketak zure hasierako jarioan ikusiko. Ez dute jakingo isilarazi dituztenik.", + "block_user": "Blokeatu %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ezin izango dituzte zure bidalketak jarraitu edo ikusi, baina blokeatuta dauden ikusi ahal izango dute.", + "while_we_review_this_you_can_take_action_against_user": "Hau berrikusten dugun bitartean, %s erabiltzailearen aurkako neurriak hartu ditzakezu" } }, "preview": { @@ -721,7 +721,7 @@ "accessibility_hint": "Ukitu birritan morroi hau baztertzeko" }, "bookmark": { - "title": "Bookmarks" + "title": "Laster-markak" } } } From e0200054c96c8876fa37636d2cd37e119beee336 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:26 +0100 Subject: [PATCH 077/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 288 +++++++++--------- 1 file changed, 144 insertions(+), 144 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 69cf3416d..f1481aa52 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -23,25 +23,25 @@ "title": "Gwall Cyhoeddi", "message": "Gwall wrth gyhoeddi'r tŵt.\nGwiriwch eich cysylltiad i'r rhyngrhwyd.", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", - "more_than_one_video": "Cannot attach more than one video." + "video_attach_with_photo": "Ni ellir ychwanegu fideo at bost sy'n cynnwys lluniau yn barod.", + "more_than_one_video": "Ni ellir ychwanegu mwy nag un fideo." } }, "edit_profile_failure": { - "title": "Edit Profile Error", - "message": "Cannot edit profile. Please try again." + "title": "Gwall Golygu Proffil", + "message": "Ni ellir golygu proffil. Ceisiwch eto." }, "sign_out": { "title": "Allgofnodi", - "message": "Are you sure you want to sign out?", + "message": "Ydych chi wir eisiau allgofnodi?", "confirm": "Allgofnodi" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", - "block_entire_domain": "Block Domain" + "title": "Ydych chi wir, wir eisiau blocio'r holl %s? Fel arfer, mae blocio neu anwybyddu pobl penodol yn broses mwy effeithiol. Ni fyddwch yn gweld cynnwys o'r parth hwnnw a bydd eich dilynwyr o'r parth hwnnw yn cael eu ddileu.", + "block_entire_domain": "Blocio parth" }, "save_photo_failure": { - "title": "Save Photo Failure", + "title": "Gwall Cadw Llun", "message": "Please enable the photo library access permission to save the photo." }, "delete_post": { @@ -89,7 +89,7 @@ "reply": "Ymateb", "report_user": "Riportio %s", "block_domain": "Blocio %s", - "unblock_domain": "Unblock %s", + "unblock_domain": "Dadflocio %s", "settings": "Gosodiadau", "delete": "Dileu" }, @@ -113,19 +113,19 @@ "open_author_profile": "Agor Proffil yr Awdur", "open_reblogger_profile": "Agor Proffil yr Ailflogwr", "reply_status": "Ymateb i Tŵt", - "toggle_reblog": "Toggle Reblog on Post", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", - "preview_image": "Preview Image" + "toggle_reblog": "Toglo Ailfloggio ar Tŵt", + "toggle_favorite": "Toglo Ffefrynnu ar Tŵt", + "toggle_content_warning": "Toglo Rhybudd Cynnwys", + "preview_image": "Rhagolygu'r Llun" }, "segmented_control": { - "previous_section": "Previous Section", + "previous_section": "Adran Flaenorol", "next_section": "Adran Nesaf" } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", + "user_reblogged": "%s wedi ailflogio", + "user_replied_to": "Wedi ymateb i %s", "show_post": "Dangos Tŵt", "show_user_profile": "Dangos proffil y defnyddiwr", "content_warning": "Rhybudd Cynnwys", @@ -181,11 +181,11 @@ "unblock": "Dadflocio", "unblock_user": "Dadflocio %s", "blocked": "Wedi blocio", - "mute": "Mute", - "mute_user": "Mute %s", - "unmute": "Unmute", - "unmute_user": "Unmute %s", - "muted": "Muted", + "mute": "Anwybyddu", + "mute_user": "Anwybyddu %s", + "unmute": "Dad-anwybyddu", + "unmute_user": "Dad-anwybyddu %s", + "muted": "Wedi anwybyddu", "edit_info": "Golygu", "show_reblogs": "Dangos Ailfloggiau", "hide_reblogs": "Cuddio Ailfloggiau" @@ -206,23 +206,23 @@ "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "suspended_warning": "Mae'r defnyddiwr hwn wedi derbyn gwaharddiad.", + "user_suspended_warning": "Mae cyfrif %s wedi derbyn gwaharddiad." } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", + "slogan": "Rhwydweithio cymdeithasol, \nyn eich dwylo chi.", + "get_started": "Cychwyn Arni", "log_in": "Mewngofnodi" }, "login": { "title": "Croeso nôl", "subtitle": "Log you in on the server you created your account on.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Mewnosod URL neu chwilio am eich gweinydd" } }, "server_picker": { @@ -231,40 +231,40 @@ "button": { "category": { "all": "Popeth", - "all_accessiblity_description": "Category: All", + "all_accessiblity_description": "Categori: Popeth", "academia": "academaidd", "activism": "gweithgarwch", "food": "bwyd", "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", - "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "games": "gemau", + "general": "cyffredinol", + "journalism": "newyddiaduraeth", + "lgbt": "LHDT+", + "regional": "rhanbarthol", + "art": "celf", + "music": "cerddoriaeth", + "tech": "technoleg" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "Gweld Llai", + "see_more": "Gweld Mwy" }, "label": { - "language": "LANGUAGE", + "language": "IAITH", "users": "DEFNYDDWYR", "category": "CATEGORI" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Chwilio cymunedau neu fewnosod URL" }, "empty_state": { - "finding_servers": "Finding available servers...", + "finding_servers": "Wrthi'n chwilio am weinyddion sydd ar gael...", "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "no_results": "Dim canlyniadau" } }, "register": { - "title": "Let’s get you set up on %s", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "title": "Rhoi popeth yn ei le ar %s", + "lets_get_you_set_up_on_domain": "Rhoi popeth yn ei le ar %s", "input": { "avatar": { "delete": "Dileu" @@ -284,8 +284,8 @@ "require": "Mae angen i'ch cyfrinair gael o leiaf:", "character_limit": "8 nod", "accessibility": { - "checked": "checked", - "unchecked": "unchecked" + "checked": "ticiwyd", + "unchecked": "na thiciwyd" }, "hint": "Your password needs at least eight characters" }, @@ -305,19 +305,19 @@ "reason": { "blocked": "%s contains a disallowed email provider", "unreachable": "%s does not seem to exist", - "taken": "%s is already in use", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", - "blank": "%s is required", - "invalid": "%s is invalid", - "too_long": "%s is too long", - "too_short": "%s is too short", - "inclusion": "%s is not a supported value" + "taken": "Defnyddir %s yn barod", + "reserved": "Mae %s yn air allweddol a chadwyd", + "accepted": "Mae angen cytuno â %s", + "blank": "Mae angen cael %s", + "invalid": "Mae %s yn annilys", + "too_long": "Mae %s yn rhy hir", + "too_short": "Mae %s yn rhy fyr", + "inclusion": "Nid yw %s yn gwerth a chefnogir" }, "special": { "username_invalid": "Username must only contain alphanumeric characters and underscores", "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", + "email_invalid": "Nid yw'n cyfeiriad e-bost dilys", "password_too_short": "Password is too short (must be at least 8 characters)" } } @@ -349,7 +349,7 @@ "title": "Gwiriwch eich blwch derbyn.", "description": "We just sent you an email. Check your junk folder if you haven’t.", "mail": "Mail", - "open_email_client": "Open Email Client" + "open_email_client": "Agor Cleient E-byst" } }, "home_timeline": { @@ -366,49 +366,49 @@ } }, "suggestion_account": { - "title": "Find People to Follow", + "title": "Chwilio a Dilyn Pobl", "follow_explain": "When you follow someone, you’ll see their posts in your home feed." }, "compose": { "title": { "new_post": "Tŵt Newydd", - "new_reply": "New Reply" + "new_reply": "Ymateb Newydd" }, "media_selection": { "camera": "Tynnu Llun", "photo_library": "Photo Library", - "browse": "Browse" + "browse": "Pori" }, "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", + "compose_action": "Cyhoeddi", "replying_to_user": "replying to %s", "attachment": { - "photo": "photo", - "video": "video", + "photo": "llun", + "video": "fideo", "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", "description_photo": "Describe the photo for the visually-impaired...", "description_video": "Describe the video for the visually-impaired...", "load_failed": "Load Failed", "upload_failed": "Upload Failed", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", + "attachment_too_large": "Mae'r atodiad yn rhy fawr", "compressing_state": "Compressing...", "server_processing_state": "Server Processing..." }, "poll": { - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", + "duration_time": "Hyd: %s", + "thirty_minutes": "30 munud", "one_hour": "1 awr", "six_hours": "6 awr", "one_day": "1 diwrnod", "three_days": "3 diwrnod", "seven_days": "7 diwrnod", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "option_number": "Opsiwn %ld", + "the_poll_is_invalid": "Nid yw'r pôl yn ddilys", + "the_poll_has_empty_option": "Mae gan y pôl opsiwn gwag" }, "content_warning": { - "placeholder": "Write an accurate warning here..." + "placeholder": "Ysgrifenwch rybudd manwl yma..." }, "visibility": { "public": "Cyhoeddus", @@ -417,31 +417,31 @@ "direct": "Only people I mention" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Lle i ychwanegu" }, "accessibility": { - "append_attachment": "Add Attachment", - "append_poll": "Add Poll", - "remove_poll": "Remove Poll", - "custom_emoji_picker": "Custom Emoji Picker", - "enable_content_warning": "Enable Content Warning", - "disable_content_warning": "Disable Content Warning", + "append_attachment": "Ychwanegu Atodiad", + "append_poll": "Ychwanegu Pôl", + "remove_poll": "Dileu Pôl", + "custom_emoji_picker": "Dewislen Emoji Bersonol", + "enable_content_warning": "Galluogi Rhybudd Cynnwys", + "disable_content_warning": "Analluogi Rhybudd Cynnwys", "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Opsiynau Tŵt", + "posting_as": "Cyhoeddi fel %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", - "toggle_poll": "Toggle Poll", - "toggle_content_warning": "Toggle Content Warning", - "append_attachment_entry": "Add Attachment - %s", + "discard_post": "Dileu Tŵt", + "publish_post": "Cyhoeddi Tŵt", + "toggle_poll": "Toglo Pôl", + "toggle_content_warning": "Toglo Rhybudd Cynnwys", + "append_attachment_entry": "Ychwanegu Atodiad - %s", "select_visibility_entry": "Select Visibility - %s" } }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Yn eich dilyn" }, "dashboard": { "posts": "postiadau", @@ -455,7 +455,7 @@ "content": "Cynnwys" }, "verified": { - "short": "Verified on %s", + "short": "Wedi dilysu ar %s", "long": "Ownership of this link was checked on %s" } }, @@ -468,28 +468,28 @@ }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Anwybyddu Cyfrif", + "message": "Parhau i anwybyddu %s" }, "confirm_unmute_user": { - "title": "Unmute Account", - "message": "Confirm to unmute %s" + "title": "Dad-anwybyddu Cyfrif", + "message": "Parhau i ddad-anwybyddu %s" }, "confirm_block_user": { - "title": "Block Account", + "title": "Blocio Cyfrif", "message": "Confirm to block %s" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Dadflocio Cyfrif", + "message": "Parhau i ddadflocio %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", + "title": "Dangos Ailfloggiau", "message": "Confirm to show reblogs" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Cuddio Ailflogiau", + "message": "Cadarnhau i guddio ailflogiau" } }, "accessibility": { @@ -500,11 +500,11 @@ } }, "follower": { - "title": "follower", + "title": "dilynwr", "footer": "Followers from other servers are not displayed." }, "following": { - "title": "following", + "title": "yn dilyn", "footer": "Follows from other servers are not displayed." }, "familiarFollowers": { @@ -518,13 +518,13 @@ "title": "Reblogged By" }, "search": { - "title": "Search", + "title": "Chwilio", "search_bar": { - "placeholder": "Search hashtags and users", - "cancel": "Cancel" + "placeholder": "Chwilio hashnodau a defnyddwyr", + "cancel": "Canslo" }, "recommend": { - "button_text": "See All", + "button_text": "Gweld Popeth", "hash_tag": { "title": "Pynciau Llosg ar Mastodon", "description": "Dyma'r hashnodau sy'n derbyn tipyn o sylw", @@ -566,30 +566,30 @@ "notification": { "title": { "Everything": "Popeth", - "Mentions": "Mentions" + "Mentions": "Crybwylliadau" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", - "reblogged_your_post": "reblogged your post", - "mentioned_you": "mentioned you", - "request_to_follow_you": "request to follow you", - "poll_has_ended": "poll has ended" + "followed_you": "wedi eich dilyn", + "favorited_your_post": "wedi ffefrynnu eich tŵt", + "reblogged_your_post": "wedi ailfloggio'ch tŵt", + "mentioned_you": "wedi sôn amdanoch", + "request_to_follow_you": "wedi gwneud cais i'ch dilyn", + "poll_has_ended": "pôl wedi dod i ben" }, "keyobard": { - "show_everything": "Show Everything", + "show_everything": "Dangos Popeth", "show_mentions": "Show Mentions" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Derbyn", + "accepted": "Wedi Derbyn", + "reject": "gwrthod", + "rejected": "Gwrthodwyd" } }, "thread": { "back_title": "Post", - "title": "Post from %s" + "title": "Tŵt gan %s" }, "settings": { "title": "Gosodiadau", @@ -617,59 +617,59 @@ "anyone": "unrhyw un", "follower": "dilynwr", "follow": "anyone I follow", - "noone": "no one", + "noone": "neb", "title": "Notify me when" } }, "preference": { - "title": "Preferences", + "title": "Dewisiadau", "true_black_dark_mode": "True black dark mode", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", + "disable_avatar_animation": "Analluogi rhithffurfiau wedi'u hanimeiddio", + "disable_emoji_animation": "Analluogi emoji wedi'u hanimeiddio", "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "open_links_in_mastodon": "Agor dolenni ym Mastodon" }, "boring_zone": { - "title": "The Boring Zone", - "account_settings": "Account Settings", - "terms": "Terms of Service", - "privacy": "Privacy Policy" + "title": "Yr Ardal Ddiflas", + "account_settings": "Gosodiadau Cyfrif", + "terms": "Telerau Gwasanaeth", + "privacy": "Polisi Preifatrwydd" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", - "signout": "Sign Out" + "title": "Yr Ardal Sbeislyd", + "clear": "Clirio Storfa Cyfryngau", + "signout": "Allgofnodi" } }, "footer": { - "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + "mastodon_description": "Mae Mastodon yn feddalwedd cod agored. Gallech roi gwybod am wallau ar GitHub: %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Cau Ffenest Gosodiadau" } }, "report": { - "title_report": "Report", - "title": "Report %s", - "step1": "Step 1 of 2", - "step2": "Step 2 of 2", + "title_report": "Riportio", + "title": "Riportio %s", + "step1": "Cam 1 o 2", + "step2": "Cam 2 o 2", "content1": "Are there any other posts you’d like to add to the report?", "content2": "Is there anything the moderators should know about this report?", "report_sent_title": "Thanks for reporting, we’ll look into this.", - "send": "Send Report", - "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED", + "send": "Anfon adroddiad", + "skip_to_send": "Anfon heb sylw", + "text_placeholder": "Teipiwch neu gludwch sylwadau ychwanegol", + "reported": "WEDI RIPORTIO", "step_one": { "step_1_of_4": "Cam 1 o 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "whats_wrong_with_this_post": "Beth sy'n bod gyda'r tŵt hwn?", + "whats_wrong_with_this_account": "Beth sy'n bod gyda'r cyfrif hwn?", + "whats_wrong_with_this_username": "Beth sy'n bod gyda %s?", + "select_the_best_match": "Dewiswch yr opsiwn gorau", + "i_dont_like_it": "Dydw i ddim yn ei hoffi", + "it_is_not_something_you_want_to_see": "Nid yw'n rhywbeth ydych chi eisiau ei weld", + "its_spam": "Mae'n sbam", + "malicious_links_fake_engagement_or_repetetive_replies": "Dolenni maleisus, ymgysylltu ffug, neu ymatebion ailadroddus", "it_violates_server_rules": "Mae'n torri rheolau'r gweinydd", "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", "its_something_else": "Mae'n rhywbeth arall", @@ -696,7 +696,7 @@ "unfollow": "Dad-ddilyn", "unfollowed": "Dad-ddilynwyd", "unfollow_user": "Dad-ddilyn %s", - "mute_user": "Mute %s", + "mute_user": "Anwybyddu %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", "block_user": "Blocio %s", "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", From c616141aee79583c12505e8c74a603829c625de5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:27 +0100 Subject: [PATCH 078/733] New translations Localizable.stringsdict (Basque) --- .../StringsConvertor/input/eu.lproj/Localizable.stringsdict | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict index 057ca4010..404deebd3 100644 --- a/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict @@ -63,13 +63,13 @@ one 1 character other - %ld characters + %ld karaktere plural.count.followed_by_and_mutual NSStringLocalizedFormatKey - %#@names@%#@count_mutual@ + %#@names@: "%#@count_mutual@ names one From 8e11d27477cdd952a8d4860c0c7fe353e38248f3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:28 +0100 Subject: [PATCH 079/733] New translations Localizable.stringsdict (Welsh) --- .../input/cy.lproj/Localizable.stringsdict | 278 +++++++++--------- 1 file changed, 139 insertions(+), 139 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict index ee167673e..045989741 100644 --- a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict @@ -13,17 +13,17 @@ NSStringFormatValueTypeKey ld zero - %ld unread notification + %ld hysbysiad heb ei ddarllen one - 1 unread notification + %ld hysbysiad heb ei ddarllen two - %ld unread notification + %ld hysbysiad heb eu darllen few - %ld unread notification + %ld hysbysiad heb eu darllen many - %ld unread notification + %ld hysbysiad heb eu darllen other - %ld unread notification + %ld hysbysiad heb eu darllen a11y.plural.count.input_limit_exceeds @@ -37,17 +37,17 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld nod one - 1 character + %ld nod two - %ld characters + %ld nod few - %ld characters + %ld nod many - %ld characters + %ld nod other - %ld nodau + %ld nod a11y.plural.count.input_limit_remains @@ -77,7 +77,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ ar ôl character_count NSStringFormatSpecTypeKey @@ -152,17 +152,17 @@ NSStringFormatValueTypeKey ld zero - post + tŵt one - post + tŵt two - post + tŵt few - posts + tŵt many - posts + tŵt other - postiau + postiadau plural.count.media @@ -200,17 +200,17 @@ NSStringFormatValueTypeKey ld zero - %ld posts + %ld post one - 1 post + %ld post two - %ld posts + %ld bost few - %ld posts + %ld post many - %ld posts + %ld post other - %ld posts + %ld post plural.count.favorite @@ -248,17 +248,17 @@ NSStringFormatValueTypeKey ld zero - %ld reblogs + %ld ailflogiau one - 1 reblog + %ld ailflog two - %ld reblogs + %ld ailflog few - %ld reblogs + %ld ailflog many - %ld reblogs + %ld ailflog other - %ld reblogs + %ld o ailflogiau plural.count.reply @@ -272,17 +272,17 @@ NSStringFormatValueTypeKey ld zero - %ld replies + %ld ymatebau one - 1 reply + %ld ymateb two - %ld replies + %ld ymateb few - %ld replies + %ld ymateb many - %ld replies + %ld o ymatebau other - %ld replies + %ld ymateb plural.count.vote @@ -296,17 +296,17 @@ NSStringFormatValueTypeKey ld zero - %ld votes + %ld pleidleisiau one - 1 vote + %ld pleidlais two - %ld votes + %ld bleidlais few - %ld votes + %ld phleidlais many - %ld votes + %ld pleidlais other - %ld votes + %ld pleidlais plural.count.voter @@ -320,17 +320,17 @@ NSStringFormatValueTypeKey ld zero - %ld voters + %ld pleidleiswyr one - 1 voter + %ld pleidleisiwr two - %ld voters + %ld bleidleisiwr few - %ld voters + %ld phleidleisiwr many - %ld voters + %ld pleidleisiwr other - %ld voters + %ld pleidleisiwr plural.people_talking @@ -344,17 +344,17 @@ NSStringFormatValueTypeKey ld zero - %ld people talking + %ld person yn trafod one - 1 people talking + %ld person yn trafod two - %ld people talking + %ld berson yn trafod few - %ld people talking + %ld o bobl yn trafod many - %ld people talking + %ld o bobl yn trafod other - %ld people talking + %ld o bobl yn trafod plural.count.following @@ -368,17 +368,17 @@ NSStringFormatValueTypeKey ld zero - %ld following + %ld yn dilyn one - 1 following + %ld yn dilyn two - %ld following + %ld yn dilyn few - %ld following + %ld yn dilyn many - %ld following + %ld yn dilyn other - %ld following + %ld yn dilyn plural.count.follower @@ -392,17 +392,17 @@ NSStringFormatValueTypeKey ld zero - %ld followers + %ld dilynwyr one - 1 follower + %ld dilynwr two - %ld followers + %ld ddilynwr few - %ld followers + %ld dilynwr many - %ld followers + %ld o ddilynwyr other - %ld followers + %ld dilynwr date.year.left @@ -416,17 +416,17 @@ NSStringFormatValueTypeKey ld zero - %ld years left + %ld blwyddyn ar ôl one - 1 year left + %ld blwyddyn ar ôl two - %ld years left + %ld flwyddyn ar ôl few - %ld years left + %ld blwyddyn ar ôl many - %ld years left + %ld blwyddyn ar ôl other - %ld years left + %ld blwyddyn ar ôl date.month.left @@ -440,17 +440,17 @@ NSStringFormatValueTypeKey ld zero - %ld months left + %ld mis ar ôl one - 1 months left + %ld mis ar ôl two - %ld months left + %ld fis ar ôl few - %ld months left + %ld mis ar ôl many - %ld months left + %ld mis ar ôl other - %ld months left + %ld mis ar ôl date.day.left @@ -464,17 +464,17 @@ NSStringFormatValueTypeKey ld zero - %ld days left + %ld diwrnod ar ôl one - 1 day left + %ld diwrnod ar ôl two - %ld days left + %ld ddiwrnod ar ôl few - %ld days left + %ld diwrnod ar ôl many - %ld days left + %ld diwrnod ar ôl other - %ld days left + %ld diwrnod ar ôl date.hour.left @@ -488,17 +488,17 @@ NSStringFormatValueTypeKey ld zero - %ld hours left + %ld awr ar ôl one - 1 hour left + %ld awr ar ôl two - %ld hours left + %ld awr ar ôl few - %ld hours left + %ld awr ar ôl many - %ld hours left + %ld awr ar ôl other - %ld hours left + %ld awr ar ôl date.minute.left @@ -512,17 +512,17 @@ NSStringFormatValueTypeKey ld zero - %ld minutes left + %ld munud ar ôl one - 1 minute left + %ld munud ar ôl two - %ld minutes left + %ld funud ar ôl few - %ld minutes left + %ld munud ar ôl many - %ld minutes left + %ld munud ar ôl other - %ld minutes left + %ld munud ar ôl date.second.left @@ -536,17 +536,17 @@ NSStringFormatValueTypeKey ld zero - %ld seconds left + %ld eiliad ar ôl one - 1 second left + %ld eiliad ar ôl two - %ld seconds left + %ld eiliad ar ôl few - %ld seconds left + %ld eiliad ar ôl many - %ld seconds left + %ld eiliad ar ôl other - %ld seconds left + %ld eiliad ar ôl date.year.ago.abbr @@ -560,17 +560,17 @@ NSStringFormatValueTypeKey ld zero - %ldy ago + %ld blwyddyn yn ôl one - 1y ago + %ld blwyddyn yn ôl two - %ldy ago + %ld flwyddyn yn ôl few - %ldy ago + %ld blwyddyn yn ôl many - %ldy ago + %ld blwyddyn yn ôl other - %ldy ago + %ld blwyddyn yn ôl date.month.ago.abbr @@ -584,17 +584,17 @@ NSStringFormatValueTypeKey ld zero - %ldM ago + %ld munud yn ôl one - 1M ago + %ld munud yn ôl two - %ldM ago + %ld funud yn ôl few - %ldM ago + %ld munud yn ôl many - %ldM ago + %ld munud yn ôl other - %ldM ago + %ld munud yn ôl date.day.ago.abbr @@ -608,17 +608,17 @@ NSStringFormatValueTypeKey ld zero - %ldd ago + %ldd yn ôl one - 1d ago + %ldd yn ôl two - %ldd ago + %ldd yn ôl few - %ldd ago + %ldd yn ôl many - %ldd ago + %ldd yn ôl other - %ldd ago + %ldd yn ôl date.hour.ago.abbr @@ -632,17 +632,17 @@ NSStringFormatValueTypeKey ld zero - %ldh ago + %ld awr yn ôl one - 1h ago + %ld awr yn ôl two - %ldh ago + %ld awr yn ôl few - %ldh ago + %ld awr yn ôl many - %ldh ago + %ld awr yn ôl other - %ldh ago + %ld awr yn ôl date.minute.ago.abbr @@ -656,17 +656,17 @@ NSStringFormatValueTypeKey ld zero - %ldm ago + %ld munud yn ôl one - 1m ago + %ld munud yn ôl two - %ldm ago + %ld funud yn ôl few - %ldm ago + %ld munud yn ôl many - %ldm ago + %ld munud yn ôl other - %ldm ago + %ld munud yn ôl date.second.ago.abbr @@ -680,17 +680,17 @@ NSStringFormatValueTypeKey ld zero - %lds ago + %ld eiliad yn ôl one - 1s ago + %ld eiliad yn ôl two - %lds ago + %ld eiliad yn ôl few - %lds ago + %ld eiliad yn ôl many - %lds ago + %ld eiliad yn ôl other - %lds ago + %ld eiliad yn ôl From 5fe93ec69eb900c3515f43c5f05a8c2a265eec62 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:29 +0100 Subject: [PATCH 080/733] New translations Intents.strings (Welsh) --- .../Intents/input/cy.lproj/Intents.strings | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings index 6877490ba..0dd18e77e 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings @@ -1,8 +1,8 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Postio ar Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Cynnwys Testun"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Postio ar Mastodon"; "HZSGTr" = "What content to post?"; @@ -28,15 +28,15 @@ "apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Cyhoeddus"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Dilynwyr yn Unig"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Postio ar Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Cyhoeddus"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Dilynwyr yn unig"; "gfePDu" = "Posting failed. ${failureReason}"; From 929166df71fbcbb9c871a67e02fc0aeb59403cf1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 18:18:30 +0100 Subject: [PATCH 081/733] New translations Intents.stringsdict (Welsh) --- .../input/cy.lproj/Intents.stringsdict | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict index 1673f7287..cf2026f13 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict @@ -13,23 +13,23 @@ NSStringFormatValueTypeKey %ld zero - %ld options + %ld opsiynau one - 1 option + %ld opsiwn two - %ld options + %ld opsiwn few - %ld options + %ld opsiwn many - %ld options + %ld o opsiynau other - %ld options + %ld o opsiynau There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Ceir %#@count_option@ ar gyfer '${visibility}'. count_option NSStringFormatSpecTypeKey @@ -37,15 +37,15 @@ NSStringFormatValueTypeKey %ld zero - %ld options + %ld opsiynau one - 1 option + %ld opsiwn two - %ld options + %ld opsiwn few - %ld options + %ld opsiwn many - %ld options + %ld o opsiynau other %ld opsiwn From 100e359b659e4d8afb114b2377c7ca751b9d44ca Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 19:16:17 +0100 Subject: [PATCH 082/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index f1481aa52..70c0288cb 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -42,11 +42,11 @@ }, "save_photo_failure": { "title": "Gwall Cadw Llun", - "message": "Please enable the photo library access permission to save the photo." + "message": "Rhowch caniatád mynediad i'r Photo Library i gadw'r llun." }, "delete_post": { "title": "Dileu Tŵt", - "message": "Are you sure you want to delete this post?" + "message": "Ydych chi wir eisiau dileu'r post hwn?" }, "clean_cache": { "title": "Clirio storfa", @@ -304,7 +304,7 @@ }, "reason": { "blocked": "%s contains a disallowed email provider", - "unreachable": "%s does not seem to exist", + "unreachable": "Nid yw %s yn bodoli", "taken": "Defnyddir %s yn barod", "reserved": "Mae %s yn air allweddol a chadwyd", "accepted": "Mae angen cytuno â %s", @@ -379,17 +379,17 @@ "photo_library": "Photo Library", "browse": "Pori" }, - "content_input_placeholder": "Type or paste what’s on your mind", + "content_input_placeholder": "Teipiwch neu gludo'r hyn sydd ar eich meddwl", "compose_action": "Cyhoeddi", - "replying_to_user": "replying to %s", + "replying_to_user": "yn ymateb i %s", "attachment": { "photo": "llun", "video": "fideo", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "attachment_broken": "Mae %s wedi torri a ni ellir\nuwchlwytho hwn i Mastodon.", "description_photo": "Describe the photo for the visually-impaired...", "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", + "load_failed": "Methwyd Llwytho", + "upload_failed": "Methwyd Uwchlwytho", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", "attachment_too_large": "Mae'r atodiad yn rhy fawr", "compressing_state": "Compressing...", @@ -412,7 +412,7 @@ }, "visibility": { "public": "Cyhoeddus", - "unlisted": "Unlisted", + "unlisted": "Heb ei rhestru", "private": "Dilynwyr yn unig", "direct": "Only people I mention" }, @@ -515,7 +515,7 @@ "title": "Favorited By" }, "reblogged_by": { - "title": "Reblogged By" + "title": "Wedi'i hybu gan" }, "search": { "title": "Chwilio", @@ -721,7 +721,7 @@ "accessibility_hint": "Double tap to dismiss this wizard" }, "bookmark": { - "title": "Bookmarks" + "title": "Tudalnodau" } } } From fd1cb0e945177f678c832a3ab74bfd8badcecf75 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 20:27:27 +0100 Subject: [PATCH 083/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 70c0288cb..1a9cde6e9 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -226,7 +226,7 @@ } }, "server_picker": { - "title": "Mastodon is made of users in different servers.", + "title": "Mae Mastodon yn cynnwys defnyddwyr o weinyddion gwahanol.", "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", "button": { "category": { @@ -287,7 +287,7 @@ "checked": "ticiwyd", "unchecked": "na thiciwyd" }, - "hint": "Your password needs at least eight characters" + "hint": "Mae angen o leiaf wyth nod yn eich cyfrinair" }, "invite": { "registration_user_invite_request": "Pam ydych chi eisiau ymuno?" @@ -303,7 +303,7 @@ "reason": "Rheswm" }, "reason": { - "blocked": "%s contains a disallowed email provider", + "blocked": "Mae %s yn defnyddio darparwr e-bost nad yw'n cael ei ganiatáu", "unreachable": "Nid yw %s yn bodoli", "taken": "Defnyddir %s yn barod", "reserved": "Mae %s yn air allweddol a chadwyd", @@ -316,16 +316,16 @@ }, "special": { "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", + "username_too_long": "Enw defnyddiwr yn rhy hir (na all fod yn fwy na 30 nodyn)", "email_invalid": "Nid yw'n cyfeiriad e-bost dilys", - "password_too_short": "Password is too short (must be at least 8 characters)" + "password_too_short": "Cyfrinair yn rhy fyr (Rhaid fod o leiaf 8 nodyn)" } } }, "server_rules": { "title": "Rhai rheolau sylfaenol.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "subtitle": "Mae'r rhain yn cael eu gosod a'u gorfodi gan gymedrolwyr %s.", + "prompt": "Wrth barhau, rydych yn cytuno â'r Telerau Gwasanaeth a Pholisi Preifatrwydd %s.", "terms_of_service": "telerau gwasanaeth", "privacy_policy": "polisi preifatrwydd", "button": { @@ -392,8 +392,8 @@ "upload_failed": "Methwyd Uwchlwytho", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", "attachment_too_large": "Mae'r atodiad yn rhy fawr", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "compressing_state": "Wrthi'n cywasgu...", + "server_processing_state": "Mae'r gweinydd yn prosesu..." }, "poll": { "duration_time": "Hyd: %s", @@ -414,7 +414,7 @@ "public": "Cyhoeddus", "unlisted": "Heb ei rhestru", "private": "Dilynwyr yn unig", - "direct": "Only people I mention" + "direct": "Dim ond pobl rwy'n eu crybwyll" }, "auto_complete": { "space_to_add": "Lle i ychwanegu" @@ -426,7 +426,7 @@ "custom_emoji_picker": "Dewislen Emoji Bersonol", "enable_content_warning": "Galluogi Rhybudd Cynnwys", "disable_content_warning": "Analluogi Rhybudd Cynnwys", - "post_visibility_menu": "Post Visibility Menu", + "post_visibility_menu": "Dewislen Breifatrwydd Post", "post_options": "Opsiynau Tŵt", "posting_as": "Cyhoeddi fel %s" }, @@ -436,7 +436,7 @@ "toggle_poll": "Toglo Pôl", "toggle_content_warning": "Toglo Rhybudd Cynnwys", "append_attachment_entry": "Ychwanegu Atodiad - %s", - "select_visibility_entry": "Select Visibility - %s" + "select_visibility_entry": "Dewis Preifatrwydd - %s" } }, "profile": { @@ -456,7 +456,7 @@ }, "verified": { "short": "Wedi dilysu ar %s", - "long": "Ownership of this link was checked on %s" + "long": "Gwiriwyd perchnogaeth y ddolen yma ar %s" } }, "segmented_control": { @@ -477,7 +477,7 @@ }, "confirm_block_user": { "title": "Blocio Cyfrif", - "message": "Confirm to block %s" + "message": "Cadarnhau i flocio %s" }, "confirm_unblock_user": { "title": "Dadflocio Cyfrif", @@ -485,7 +485,7 @@ }, "confirm_show_reblogs": { "title": "Dangos Ailfloggiau", - "message": "Confirm to show reblogs" + "message": "Cadarnhau i ddangos hybiau" }, "confirm_hide_reblogs": { "title": "Cuddio Ailflogiau", @@ -501,18 +501,18 @@ }, "follower": { "title": "dilynwr", - "footer": "Followers from other servers are not displayed." + "footer": "Ni ddangosir dilynwyr o weinyddion eraill." }, "following": { "title": "yn dilyn", - "footer": "Follows from other servers are not displayed." + "footer": "Ni ddangosir dilynion o weinyddion eraill." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Dilynwyr sy'n gyfarwydd ichi", + "followed_by_names": "Dilynwyd gan %s" }, "favorited_by": { - "title": "Favorited By" + "title": "Ffefrynnwyd gan" }, "reblogged_by": { "title": "Wedi'i hybu gan" @@ -531,8 +531,8 @@ "people_talking": "%s person yn trafod" }, "accounts": { - "title": "Accounts you might like", - "description": "You may like to follow these accounts", + "title": "Cyfrifon ar eich cyfer", + "description": "Cyfrifon sydd efallai o ddiddordeb ichi", "follow": "Dilyn" } }, @@ -609,24 +609,24 @@ }, "notifications": { "title": "Hysbysiadau", - "favorites": "Favorites my post", - "follows": "Follows me", - "boosts": "Reblogs my post", - "mentions": "Mentions me", + "favorites": "Yn ffefrynnu fy mhost", + "follows": "Yn fy nilyn", + "boosts": "Yn hybu fy mhost", + "mentions": "Yn sôn amdana i", "trigger": { "anyone": "unrhyw un", "follower": "dilynwr", - "follow": "anyone I follow", + "follow": "unrhyw un o'm dilynion", "noone": "neb", - "title": "Notify me when" + "title": "Rhowch wybod i mi pan" } }, "preference": { "title": "Dewisiadau", - "true_black_dark_mode": "True black dark mode", + "true_black_dark_mode": "Gwedd tywyll go iawn", "disable_avatar_animation": "Analluogi rhithffurfiau wedi'u hanimeiddio", "disable_emoji_animation": "Analluogi emoji wedi'u hanimeiddio", - "using_default_browser": "Use default browser to open links", + "using_default_browser": "Defnyddio porwr rhagosodedig i agor dolenni", "open_links_in_mastodon": "Agor dolenni ym Mastodon" }, "boring_zone": { @@ -655,7 +655,7 @@ "step2": "Cam 2 o 2", "content1": "Are there any other posts you’d like to add to the report?", "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", + "report_sent_title": "Diolch am adrodd, byddwn yn ymchwilio i hyn.", "send": "Anfon adroddiad", "skip_to_send": "Anfon heb sylw", "text_placeholder": "Teipiwch neu gludwch sylwadau ychwanegol", @@ -671,27 +671,27 @@ "its_spam": "Mae'n sbam", "malicious_links_fake_engagement_or_repetetive_replies": "Dolenni maleisus, ymgysylltu ffug, neu ymatebion ailadroddus", "it_violates_server_rules": "Mae'n torri rheolau'r gweinydd", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "you_are_aware_that_it_breaks_specific_rules": "Rydych yn ymwybodol ei fod yn torri rheolau penodol", "its_something_else": "Mae'n rhywbeth arall", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "the_issue_does_not_fit_into_other_categories": "Nid yw'r mater yn ffitio i gategorïau eraill" }, "step_two": { "step_2_of_4": "Cam 2 o 4", - "which_rules_are_being_violated": "Which rules are being violated?", + "which_rules_are_being_violated": "Pa reolau sy'n cael eu torri?", "select_all_that_apply": "Dewiswch bob un sy'n berthnasol", "i_just_don’t_like_it": "Dydw i ddim yn ei hoffi" }, "step_three": { "step_3_of_4": "Cam 3 o 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", + "are_there_any_posts_that_back_up_this_report": "Oes postiadau eraill sy'n cefnogi'r adroddiad hwn?", "select_all_that_apply": "Dewiswch bob un sy'n berthnasol" }, "step_four": { "step_4_of_4": "Cam 4 o 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "is_there_anything_else_we_should_know": "Oes unrhyw beth arall y dylem ei wybod?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", + "dont_want_to_see_this": "Ddim eisiau gweld hwn?", "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", "unfollow": "Dad-ddilyn", "unfollowed": "Dad-ddilynwyd", @@ -712,13 +712,13 @@ }, "account_list": { "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", - "dismiss_account_switcher": "Dismiss Account Switcher", + "dismiss_account_switcher": "Diddymu Newidiwr Cyfrifon", "add_account": "Ychwanegu Cyfrif" }, "wizard": { "new_in_mastodon": "Newydd i Mastodon", "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", - "accessibility_hint": "Double tap to dismiss this wizard" + "accessibility_hint": "Tapiwch dwywaith i ddiddymu'r dewin hwn" }, "bookmark": { "title": "Tudalnodau" From a0780aaf96ec7064481392fed3fef6c7ab2edcf2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 20:27:28 +0100 Subject: [PATCH 084/733] New translations Localizable.stringsdict (Welsh) --- .../input/cy.lproj/Localizable.stringsdict | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict index 045989741..5e374e92d 100644 --- a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict @@ -128,17 +128,17 @@ NSStringFormatValueTypeKey ld zero - Followed by %1$@, and %ld mutuals + Dilynwyd gan %1$@, a %ld mewn cyffredin one - Followed by %1$@, and another mutual + Dilynwyd gan %1$@, a pherson gyffredin two - Followed by %1$@, and %ld mutuals + Dilynwyd gan %1$@, a %ld mewn cyffredin few - Followed by %1$@, and %ld mutuals + Dilynwyd gan %1$@, a %ld mewn cyffredin many - Followed by %1$@, and %ld mutuals + Dilynwyd gan %1$@, a %ld mewn cyffredin other - Followed by %1$@, and %ld mutuals + Dilynwyd gan %1$@, a %ld mewn cyffredin plural.count.metric_formatted.post @@ -224,17 +224,17 @@ NSStringFormatValueTypeKey ld zero - %ld favorites + %ld ffefrynnau one - 1 favorite + %ld ffefryn two - %ld favorites + %ld ffefryn few - %ld favorites + %ld ffefryn many - %ld favorites + %ld ffefryn other - %ld favorites + %ld ffefryn plural.count.reblog From 51ca8b1d59989f399de894fa4fe50797f604a86c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 20:27:29 +0100 Subject: [PATCH 085/733] New translations Intents.strings (Welsh) --- .../Intents/input/cy.lproj/Intents.strings | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings index 0dd18e77e..deb0d5ec9 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings @@ -4,29 +4,29 @@ "CsR7G2" = "Postio ar Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Pa gynnwys i bostio?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Methwyd postio"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Rheswm y Gwall"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Cyhoeddi Post â chynnwys testun"; "RxSqsb" = "Post"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Postio ${content} ar Mastodon"; "ZKJSNu" = "Post"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Preifatrwydd"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Preifatrwydd Post"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Ceir ${count} opsiwn ar gyfer ‘Cyhoeddus’."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Ceir ${count} opsiwn ar gyfer ‘Dilynwyr yn Unig’."; "ayoYEb-dYQ5NN" = "${content}, Cyhoeddus"; @@ -38,9 +38,9 @@ "ehFLjY" = "Dilynwyr yn unig"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Methwyd postio. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Cyhoeddwyd y post yn llwyddiannus."; "oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; @@ -48,4 +48,4 @@ "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Cyhoeddwyd y post yn llwyddiannus. "; From 3cad07733cbafa47008d3ecebb52b981bef151f9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 20:27:30 +0100 Subject: [PATCH 086/733] New translations Intents.stringsdict (Welsh) --- .../StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict index cf2026f13..1f37f6a45 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + Ceir %#@count_option@ ar gyfer '${content}'. count_option NSStringFormatSpecTypeKey From 5491d3f53c35d5ff5f9cae920afdb612630ef42d Mon Sep 17 00:00:00 2001 From: Jonas Vacek Date: Sun, 20 Nov 2022 21:49:33 +0100 Subject: [PATCH 087/733] Issue Template for a Feature Request form --- .github/ISSUE_TEMPLATE/feature.yml | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature.yml diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 000000000..b16e2b772 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,48 @@ +--- +name: 🛠️ Feature Request +description: Suggest an idea to help us improve W&B +title: "[Feature]: " +labels: + - "feature_request" + +body: + - type: markdown + attributes: + value: | + **Thanks :heart: for taking the time to fill out this feature request report!** + We kindly ask that you search to see if an issue [already exists](https://github.com/mastodon/mastodon-ios/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature. + + We are also happy to accept contributions from our users. For more details see [here](https://github.com/mastodon/mastodon-ios/blob/develop/Documentation/CONTRIBUTING.md). + + - type: textarea + attributes: + label: Description + description: | + A clear and concise description of the feature you're interested in. + validations: + required: true + + - type: textarea + attributes: + label: Suggested Solution + description: | + Describe the solution you'd like. A clear and concise description of what you want to happen. + validations: + required: true + + - type: textarea + attributes: + label: Alternatives + description: | + Describe alternatives you've considered. + A clear and concise description of any alternative solutions or features you've considered. + validations: + required: false + + - type: textarea + attributes: + label: Additional Context + description: | + Add any other context about the problem here. + validations: + required: false From 228abd1ebcef779ed130bd870708cca2a1ae9c54 Mon Sep 17 00:00:00 2001 From: Jonas Vacek Date: Sun, 20 Nov 2022 21:51:13 +0100 Subject: [PATCH 088/733] Update feature.yml --- .github/ISSUE_TEMPLATE/feature.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index b16e2b772..b849515de 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -1,6 +1,6 @@ --- name: 🛠️ Feature Request -description: Suggest an idea to help us improve W&B +description: Suggest an idea to help us improve title: "[Feature]: " labels: - "feature_request" From 1f25b77bcd5084e3e24274d36d6b85fe485b9ccb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 20 Nov 2022 23:08:08 +0100 Subject: [PATCH 089/733] New translations Intents.strings (Welsh) --- .../StringsConvertor/Intents/input/cy.lproj/Intents.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings index deb0d5ec9..11007d059 100644 --- a/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings @@ -42,9 +42,9 @@ "k7dbKQ" = "Cyhoeddwyd y post yn llwyddiannus."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "I gadarnhau, rydych chi am ddewis ‘Cyhoeddus’?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "I gadarnhau, rydych chi am ddewis ‘Dilynwyr yn Unig’?"; "rM6dvp" = "URL"; From 59165bf043ea0456df78c278894eb3a5a244e8d4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 00:10:58 +0100 Subject: [PATCH 090/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 1a9cde6e9..3cab04697 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -165,9 +165,9 @@ }, "visibility": { "unlisted": "Gall pawb weld y post hwn ond nid yn y ffrwd cyhoeddus.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "private": "Dim ond eu dilynwyr nhw sy'n gallu gweld y post hwn.", + "private_from_me": "Dim ond fy nilynwyr ni sy'n gallu gweld y post hwn.", + "direct": "Dim ond y ddefnyddiwr â soniwyd sy'n gallu gweld y post hwn." } }, "friendship": { @@ -202,10 +202,10 @@ }, "header": { "no_status_found": "Ni Chanfuwyd Post", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "blocking_warning": "Ni allwch gweld proffil y ddefnyddiwr hwn\nos ydych wedi'u blocio.\nMae'ch proffil chi yn edrych fel hyn iddynt.", + "user_blocking_warning": "Ni allwch gweld proffil %s\nos ydych wedi'u blocio.\nMae'ch proffil chi yn edrych fel hyn iddynt.", + "blocked_warning": "Ni allwch gweld proffil y ddefnyddiwr hwn\ngan eu bod wedi eich blocio chi.", + "user_blocked_warning": "Ni allwch gweld proffil %s\ngan eu bod wedi eich blocio chi.", "suspended_warning": "Mae'r defnyddiwr hwn wedi derbyn gwaharddiad.", "user_suspended_warning": "Mae cyfrif %s wedi derbyn gwaharddiad." } @@ -220,14 +220,14 @@ }, "login": { "title": "Croeso nôl", - "subtitle": "Log you in on the server you created your account on.", + "subtitle": "Mewngofnodi ar y gweinydd y rydych chi wedi creu cyfrif arno.", "server_search_field": { "placeholder": "Mewnosod URL neu chwilio am eich gweinydd" } }, "server_picker": { "title": "Mae Mastodon yn cynnwys defnyddwyr o weinyddion gwahanol.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "Dewiswch gweinydd yn ôl eich lleoliad, diddordebau, neu defnydd cyffredin. Gallwch siarad gydag unrhywun ar Mastodon, yn annibynnol o weinyddion chi.", "button": { "category": { "all": "Popeth", @@ -258,7 +258,7 @@ }, "empty_state": { "finding_servers": "Wrthi'n chwilio am weinyddion sydd ar gael...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", + "bad_network": "Digwyddodd gwall wrth lwytho'r data. Gwiriwch eich cyswllt â'r rhyngrwyd.", "no_results": "Dim canlyniadau" } }, @@ -315,7 +315,7 @@ "inclusion": "Nid yw %s yn gwerth a chefnogir" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", + "username_invalid": "Dylai enwau ddefnyddiwr gynnwys nodau alffaniwmerig a thanlinellau yn unig", "username_too_long": "Enw defnyddiwr yn rhy hir (na all fod yn fwy na 30 nodyn)", "email_invalid": "Nid yw'n cyfeiriad e-bost dilys", "password_too_short": "Cyfrinair yn rhy fyr (Rhaid fod o leiaf 8 nodyn)" @@ -342,12 +342,12 @@ }, "dont_receive_email": { "title": "Gwiriwch eich e-byst", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "description": "Gwiriwch a yw eich cyfeiriad e-bost yn gywir a hefyd eich ffolder 'junk' os nad ydych wedi ei gwneud.", "resend_email": "Ailanfon E-bost" }, "open_email_app": { "title": "Gwiriwch eich blwch derbyn.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", + "description": "Rydym newydd anfon e-bost atoch chi. Gwiriwch eich ffolder 'junk' os nad ydych wedi ei gwneud.", "mail": "Mail", "open_email_client": "Agor Cleient E-byst" } @@ -361,7 +361,7 @@ "Publishing": "Wrthi'n cyhoeddi...", "accessibility": { "logo_label": "Botwm Logo", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_hint": "Tapiwch i sgrolio i'r frig, a thapiwch eto er mwyn mynd i'r lleoliad blaenorol" } } }, @@ -386,11 +386,11 @@ "photo": "llun", "video": "fideo", "attachment_broken": "Mae %s wedi torri a ni ellir\nuwchlwytho hwn i Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired...", + "description_photo": "Disgrifio i'r rheini â nam ar eu golwg...", + "description_video": "Disgrifio i'r rheini â nam ar eu golwg...", "load_failed": "Methwyd Llwytho", "upload_failed": "Methwyd Uwchlwytho", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", + "can_not_recognize_this_media_attachment": "Ni ellir dilysu'r atodiad cyfrwng", "attachment_too_large": "Mae'r atodiad yn rhy fawr", "compressing_state": "Wrthi'n cywasgu...", "server_processing_state": "Mae'r gweinydd yn prosesu..." @@ -558,7 +558,7 @@ "community": "Cymuned", "for_you": "I Ti" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Dyma'r postiadau sy'n denu tipyn o sylw yn eich cŵr Mastodon." }, "favorite": { "title": "Eich Ffefrynnau" @@ -578,7 +578,7 @@ }, "keyobard": { "show_everything": "Dangos Popeth", - "show_mentions": "Show Mentions" + "show_mentions": "Dangos Crybwylliadau" }, "follow_request": { "accept": "Derbyn", From 45445ebd82b7aad965fc2c74aaa4ad8ea56f47dd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:21:56 +0100 Subject: [PATCH 091/733] New translations Localizable.stringsdict (English) --- .../input/en.lproj/Localizable.stringsdict | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict index 297e6675a..788eb95fc 100644 --- a/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds @@ -60,14 +60,8 @@ NSStringPluralRuleType NSStringFormatValueTypeKey ld - zero - no characters one 1 character - few - %ld characters - many - %ld characters other %ld characters From f3058e2e03028b45927471cd6a22a7c82f431020 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:02 +0100 Subject: [PATCH 092/733] New translations Localizable.stringsdict (Russian) --- .../StringsConvertor/input/ru.lproj/Localizable.stringsdict | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict index c9552a9e4..d43386ad9 100644 --- a/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict @@ -15,11 +15,11 @@ one 1 unread notification few - %ld unread notification + %ld unread notifications many - %ld unread notification + %ld unread notifications other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From ec8ef97649468581bea519290e0b2bc48f413fe4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:03 +0100 Subject: [PATCH 093/733] New translations Localizable.stringsdict (Portuguese) --- .../StringsConvertor/input/pt.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict index eabdc3c32..788eb95fc 100644 --- a/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From 518449d26f56bf14bd928b94b3ebeabd08a7e532 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:04 +0100 Subject: [PATCH 094/733] New translations Localizable.stringsdict (Dutch) --- .../StringsConvertor/input/nl.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict index 84769b0c1..29d0ec841 100644 --- a/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From 84d405c2b02f2ba334bc283f0b264f8173d08b95 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:11 +0100 Subject: [PATCH 095/733] New translations Localizable.stringsdict (Romanian) --- .../StringsConvertor/input/ro.lproj/Localizable.stringsdict | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict index 9df2162b0..669272590 100644 --- a/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict @@ -15,9 +15,9 @@ one 1 unread notification few - %ld unread notification + %ld unread notifications other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From e54903636c7281b2890449f2e5d87261cda94a52 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:15 +0100 Subject: [PATCH 096/733] New translations Localizable.stringsdict (Danish) --- .../StringsConvertor/input/da.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict index eabdc3c32..788eb95fc 100644 --- a/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From 7c625042d2eb43833a1835844a413f11b5d2e08d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:19 +0100 Subject: [PATCH 097/733] New translations Localizable.stringsdict (Sinhala) --- .../StringsConvertor/input/si.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/si.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/si.lproj/Localizable.stringsdict index eabdc3c32..788eb95fc 100644 --- a/Localization/StringsConvertor/input/si.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/si.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From c6db39d5cf6fb195e49b7006266b8572c5a9b839 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:20 +0100 Subject: [PATCH 098/733] New translations Localizable.stringsdict (Indonesian) --- .../StringsConvertor/input/id.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict index 9b8aca01c..7e88bdf69 100644 --- a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict @@ -13,7 +13,7 @@ NSStringFormatValueTypeKey ld other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From faf4b98aebdb34fe4834c2ccfedeeaa8ce5e5b24 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:21 +0100 Subject: [PATCH 099/733] New translations Localizable.stringsdict (English, United States) --- .../StringsConvertor/input/en-US.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict index eabdc3c32..788eb95fc 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From 9b008263117f75c7640db55bdca37c16a3948f20 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:22 +0100 Subject: [PATCH 100/733] New translations Localizable.stringsdict (Hindi) --- .../StringsConvertor/input/hi.lproj/Localizable.stringsdict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict index eabdc3c32..788eb95fc 100644 --- a/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From 79a5c190c39d12c9bf036215aca9e925804de9c2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 04:22:23 +0100 Subject: [PATCH 101/733] New translations Localizable.stringsdict (Latvian) --- .../StringsConvertor/input/lv.lproj/Localizable.stringsdict | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict index ac30b4f8b..0287a83a5 100644 --- a/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict @@ -13,11 +13,11 @@ NSStringFormatValueTypeKey ld zero - %ld unread notification + %ld unread notifications one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds From a9a7455e3e386c8a4c5598f45d3c98122e6c7d5a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 05:28:38 +0100 Subject: [PATCH 102/733] New translations app.json (Aragonese) --- .../StringsConvertor/input/an.lproj/app.json | 727 ++++++++++++++++++ 1 file changed, 727 insertions(+) create mode 100644 Localization/StringsConvertor/input/an.lproj/app.json diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json new file mode 100644 index 000000000..3113ada74 --- /dev/null +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -0,0 +1,727 @@ +{ + "common": { + "alerts": { + "common": { + "please_try_again": "Please try again.", + "please_try_again_later": "Please try again later." + }, + "sign_up_failure": { + "title": "Sign Up Failure" + }, + "server_error": { + "title": "Server Error" + }, + "vote_failure": { + "title": "Vote Failure", + "poll_ended": "The poll has ended" + }, + "discard_post_content": { + "title": "Discard Draft", + "message": "Confirm to discard composed post content." + }, + "publish_post_failure": { + "title": "Publish Failure", + "message": "Failed to publish the post.\nPlease check your internet connection.", + "attachments_message": { + "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", + "more_than_one_video": "Cannot attach more than one video." + } + }, + "edit_profile_failure": { + "title": "Edit Profile Error", + "message": "Cannot edit profile. Please try again." + }, + "sign_out": { + "title": "Sign Out", + "message": "Are you sure you want to sign out?", + "confirm": "Sign Out" + }, + "block_domain": { + "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", + "block_entire_domain": "Block Domain" + }, + "save_photo_failure": { + "title": "Save Photo Failure", + "message": "Please enable the photo library access permission to save the photo." + }, + "delete_post": { + "title": "Delete Post", + "message": "Are you sure you want to delete this post?" + }, + "clean_cache": { + "title": "Clean Cache", + "message": "Successfully cleaned %s cache." + } + }, + "controls": { + "actions": { + "back": "Back", + "next": "Next", + "previous": "Previous", + "open": "Open", + "add": "Add", + "remove": "Remove", + "edit": "Edit", + "save": "Save", + "ok": "OK", + "done": "Done", + "confirm": "Confirm", + "continue": "Continue", + "compose": "Compose", + "cancel": "Cancel", + "discard": "Discard", + "try_again": "Try Again", + "take_photo": "Take Photo", + "save_photo": "Save Photo", + "copy_photo": "Copy Photo", + "sign_in": "Log in", + "sign_up": "Create account", + "see_more": "See More", + "preview": "Preview", + "share": "Share", + "share_user": "Share %s", + "share_post": "Share Post", + "open_in_safari": "Open in Safari", + "open_in_browser": "Open in Browser", + "find_people": "Find people to follow", + "manually_search": "Manually search instead", + "skip": "Skip", + "reply": "Reply", + "report_user": "Report %s", + "block_domain": "Block %s", + "unblock_domain": "Unblock %s", + "settings": "Settings", + "delete": "Delete" + }, + "tabs": { + "home": "Home", + "search": "Search", + "notification": "Notification", + "profile": "Profile" + }, + "keyboard": { + "common": { + "switch_to_tab": "Switch to %s", + "compose_new_post": "Compose New Post", + "show_favorites": "Show Favorites", + "open_settings": "Open Settings" + }, + "timeline": { + "previous_status": "Previous Post", + "next_status": "Next Post", + "open_status": "Open Post", + "open_author_profile": "Open Author's Profile", + "open_reblogger_profile": "Open Reblogger's Profile", + "reply_status": "Reply to Post", + "toggle_reblog": "Toggle Reblog on Post", + "toggle_favorite": "Toggle Favorite on Post", + "toggle_content_warning": "Toggle Content Warning", + "preview_image": "Preview Image" + }, + "segmented_control": { + "previous_section": "Previous Section", + "next_section": "Next Section" + } + }, + "status": { + "user_reblogged": "%s reblogged", + "user_replied_to": "Replied to %s", + "show_post": "Show Post", + "show_user_profile": "Show user profile", + "content_warning": "Content Warning", + "sensitive_content": "Sensitive Content", + "media_content_warning": "Tap anywhere to reveal", + "tap_to_reveal": "Tap to reveal", + "poll": { + "vote": "Vote", + "closed": "Closed" + }, + "meta_entity": { + "url": "Link: %s", + "hashtag": "Hashtag: %s", + "mention": "Show Profile: %s", + "email": "Email address: %s" + }, + "actions": { + "reply": "Reply", + "reblog": "Reblog", + "unreblog": "Undo reblog", + "favorite": "Favorite", + "unfavorite": "Unfavorite", + "menu": "Menu", + "hide": "Hide", + "show_image": "Show image", + "show_gif": "Show GIF", + "show_video_player": "Show video player", + "tap_then_hold_to_show_menu": "Tap then hold to show menu" + }, + "tag": { + "url": "URL", + "mention": "Mention", + "link": "Link", + "hashtag": "Hashtag", + "email": "Email", + "emoji": "Emoji" + }, + "visibility": { + "unlisted": "Everyone can see this post but not display in the public timeline.", + "private": "Only their followers can see this post.", + "private_from_me": "Only my followers can see this post.", + "direct": "Only mentioned user can see this post." + } + }, + "friendship": { + "follow": "Follow", + "following": "Following", + "request": "Request", + "pending": "Pending", + "block": "Block", + "block_user": "Block %s", + "block_domain": "Block %s", + "unblock": "Unblock", + "unblock_user": "Unblock %s", + "blocked": "Blocked", + "mute": "Mute", + "mute_user": "Mute %s", + "unmute": "Unmute", + "unmute_user": "Unmute %s", + "muted": "Muted", + "edit_info": "Edit Info", + "show_reblogs": "Show Reblogs", + "hide_reblogs": "Hide Reblogs" + }, + "timeline": { + "filtered": "Filtered", + "timestamp": { + "now": "Now" + }, + "loader": { + "load_missing_posts": "Load missing posts", + "loading_missing_posts": "Loading missing posts...", + "show_more_replies": "Show more replies" + }, + "header": { + "no_status_found": "No Post Found", + "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", + "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", + "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", + "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "suspended_warning": "This user has been suspended.", + "user_suspended_warning": "%s’s account has been suspended." + } + } + } + }, + "scene": { + "welcome": { + "slogan": "Social networking\nback in your hands.", + "get_started": "Get Started", + "log_in": "Log In" + }, + "login": { + "title": "Welcome back", + "subtitle": "Log you in on the server you created your account on.", + "server_search_field": { + "placeholder": "Enter URL or search for your server" + } + }, + "server_picker": { + "title": "Mastodon is made of users in different servers.", + "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "button": { + "category": { + "all": "All", + "all_accessiblity_description": "Category: All", + "academia": "academia", + "activism": "activism", + "food": "food", + "furry": "furry", + "games": "games", + "general": "general", + "journalism": "journalism", + "lgbt": "lgbt", + "regional": "regional", + "art": "art", + "music": "music", + "tech": "tech" + }, + "see_less": "See Less", + "see_more": "See More" + }, + "label": { + "language": "LANGUAGE", + "users": "USERS", + "category": "CATEGORY" + }, + "input": { + "search_servers_or_enter_url": "Search communities or enter URL" + }, + "empty_state": { + "finding_servers": "Finding available servers...", + "bad_network": "Something went wrong while loading the data. Check your internet connection.", + "no_results": "No results" + } + }, + "register": { + "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "input": { + "avatar": { + "delete": "Delete" + }, + "username": { + "placeholder": "username", + "duplicate_prompt": "This username is taken." + }, + "display_name": { + "placeholder": "display name" + }, + "email": { + "placeholder": "email" + }, + "password": { + "placeholder": "password", + "require": "Your password needs at least:", + "character_limit": "8 characters", + "accessibility": { + "checked": "checked", + "unchecked": "unchecked" + }, + "hint": "Your password needs at least eight characters" + }, + "invite": { + "registration_user_invite_request": "Why do you want to join?" + } + }, + "error": { + "item": { + "username": "Username", + "email": "Email", + "password": "Password", + "agreement": "Agreement", + "locale": "Locale", + "reason": "Reason" + }, + "reason": { + "blocked": "%s contains a disallowed email provider", + "unreachable": "%s does not seem to exist", + "taken": "%s is already in use", + "reserved": "%s is a reserved keyword", + "accepted": "%s must be accepted", + "blank": "%s is required", + "invalid": "%s is invalid", + "too_long": "%s is too long", + "too_short": "%s is too short", + "inclusion": "%s is not a supported value" + }, + "special": { + "username_invalid": "Username must only contain alphanumeric characters and underscores", + "username_too_long": "Username is too long (can’t be longer than 30 characters)", + "email_invalid": "This is not a valid email address", + "password_too_short": "Password is too short (must be at least 8 characters)" + } + } + }, + "server_rules": { + "title": "Some ground rules.", + "subtitle": "These are set and enforced by the %s moderators.", + "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "terms_of_service": "terms of service", + "privacy_policy": "privacy policy", + "button": { + "confirm": "I Agree" + } + }, + "confirm_email": { + "title": "One last thing.", + "subtitle": "Tap the link we emailed to you to verify your account.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "button": { + "open_email_app": "Open Email App", + "resend": "Resend" + }, + "dont_receive_email": { + "title": "Check your email", + "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "resend_email": "Resend Email" + }, + "open_email_app": { + "title": "Check your inbox.", + "description": "We just sent you an email. Check your junk folder if you haven’t.", + "mail": "Mail", + "open_email_client": "Open Email Client" + } + }, + "home_timeline": { + "title": "Home", + "navigation_bar_state": { + "offline": "Offline", + "new_posts": "See new posts", + "published": "Published!", + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } + } + }, + "suggestion_account": { + "title": "Find People to Follow", + "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + }, + "compose": { + "title": { + "new_post": "New Post", + "new_reply": "New Reply" + }, + "media_selection": { + "camera": "Take Photo", + "photo_library": "Photo Library", + "browse": "Browse" + }, + "content_input_placeholder": "Type or paste what’s on your mind", + "compose_action": "Publish", + "replying_to_user": "replying to %s", + "attachment": { + "photo": "photo", + "video": "video", + "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "description_photo": "Describe the photo for the visually-impaired...", + "description_video": "Describe the video for the visually-impaired...", + "load_failed": "Load Failed", + "upload_failed": "Upload Failed", + "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", + "attachment_too_large": "Attachment too large", + "compressing_state": "Compressing...", + "server_processing_state": "Server Processing..." + }, + "poll": { + "duration_time": "Duration: %s", + "thirty_minutes": "30 minutes", + "one_hour": "1 Hour", + "six_hours": "6 Hours", + "one_day": "1 Day", + "three_days": "3 Days", + "seven_days": "7 Days", + "option_number": "Option %ld", + "the_poll_is_invalid": "The poll is invalid", + "the_poll_has_empty_option": "The poll has empty option" + }, + "content_warning": { + "placeholder": "Write an accurate warning here..." + }, + "visibility": { + "public": "Public", + "unlisted": "Unlisted", + "private": "Followers only", + "direct": "Only people I mention" + }, + "auto_complete": { + "space_to_add": "Space to add" + }, + "accessibility": { + "append_attachment": "Add Attachment", + "append_poll": "Add Poll", + "remove_poll": "Remove Poll", + "custom_emoji_picker": "Custom Emoji Picker", + "enable_content_warning": "Enable Content Warning", + "disable_content_warning": "Disable Content Warning", + "post_visibility_menu": "Post Visibility Menu", + "post_options": "Post Options", + "posting_as": "Posting as %s" + }, + "keyboard": { + "discard_post": "Discard Post", + "publish_post": "Publish Post", + "toggle_poll": "Toggle Poll", + "toggle_content_warning": "Toggle Content Warning", + "append_attachment_entry": "Add Attachment - %s", + "select_visibility_entry": "Select Visibility - %s" + } + }, + "profile": { + "header": { + "follows_you": "Follows You" + }, + "dashboard": { + "posts": "posts", + "following": "following", + "followers": "followers" + }, + "fields": { + "add_row": "Add Row", + "placeholder": { + "label": "Label", + "content": "Content" + }, + "verified": { + "short": "Verified on %s", + "long": "Ownership of this link was checked on %s" + } + }, + "segmented_control": { + "posts": "Posts", + "replies": "Replies", + "posts_and_replies": "Posts and Replies", + "media": "Media", + "about": "About" + }, + "relationship_action_alert": { + "confirm_mute_user": { + "title": "Mute Account", + "message": "Confirm to mute %s" + }, + "confirm_unmute_user": { + "title": "Unmute Account", + "message": "Confirm to unmute %s" + }, + "confirm_block_user": { + "title": "Block Account", + "message": "Confirm to block %s" + }, + "confirm_unblock_user": { + "title": "Unblock Account", + "message": "Confirm to unblock %s" + }, + "confirm_show_reblogs": { + "title": "Show Reblogs", + "message": "Confirm to show reblogs" + }, + "confirm_hide_reblogs": { + "title": "Hide Reblogs", + "message": "Confirm to hide reblogs" + } + }, + "accessibility": { + "show_avatar_image": "Show avatar image", + "edit_avatar_image": "Edit avatar image", + "show_banner_image": "Show banner image", + "double_tap_to_open_the_list": "Double tap to open the list" + } + }, + "follower": { + "title": "follower", + "footer": "Followers from other servers are not displayed." + }, + "following": { + "title": "following", + "footer": "Follows from other servers are not displayed." + }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, + "search": { + "title": "Search", + "search_bar": { + "placeholder": "Search hashtags and users", + "cancel": "Cancel" + }, + "recommend": { + "button_text": "See All", + "hash_tag": { + "title": "Trending on Mastodon", + "description": "Hashtags that are getting quite a bit of attention", + "people_talking": "%s people are talking" + }, + "accounts": { + "title": "Accounts you might like", + "description": "You may like to follow these accounts", + "follow": "Follow" + } + }, + "searching": { + "segment": { + "all": "All", + "people": "People", + "hashtags": "Hashtags", + "posts": "Posts" + }, + "empty_state": { + "no_results": "No results" + }, + "recent_search": "Recent searches", + "clear": "Clear" + } + }, + "discovery": { + "tabs": { + "posts": "Posts", + "hashtags": "Hashtags", + "news": "News", + "community": "Community", + "for_you": "For You" + }, + "intro": "These are the posts gaining traction in your corner of Mastodon." + }, + "favorite": { + "title": "Your Favorites" + }, + "notification": { + "title": { + "Everything": "Everything", + "Mentions": "Mentions" + }, + "notification_description": { + "followed_you": "followed you", + "favorited_your_post": "favorited your post", + "reblogged_your_post": "reblogged your post", + "mentioned_you": "mentioned you", + "request_to_follow_you": "request to follow you", + "poll_has_ended": "poll has ended" + }, + "keyobard": { + "show_everything": "Show Everything", + "show_mentions": "Show Mentions" + }, + "follow_request": { + "accept": "Accept", + "accepted": "Accepted", + "reject": "reject", + "rejected": "Rejected" + } + }, + "thread": { + "back_title": "Post", + "title": "Post from %s" + }, + "settings": { + "title": "Settings", + "section": { + "appearance": { + "title": "Appearance", + "automatic": "Automatic", + "light": "Always Light", + "dark": "Always Dark" + }, + "look_and_feel": { + "title": "Look and Feel", + "use_system": "Use System", + "really_dark": "Really Dark", + "sorta_dark": "Sorta Dark", + "light": "Light" + }, + "notifications": { + "title": "Notifications", + "favorites": "Favorites my post", + "follows": "Follows me", + "boosts": "Reblogs my post", + "mentions": "Mentions me", + "trigger": { + "anyone": "anyone", + "follower": "a follower", + "follow": "anyone I follow", + "noone": "no one", + "title": "Notify me when" + } + }, + "preference": { + "title": "Preferences", + "true_black_dark_mode": "True black dark mode", + "disable_avatar_animation": "Disable animated avatars", + "disable_emoji_animation": "Disable animated emojis", + "using_default_browser": "Use default browser to open links", + "open_links_in_mastodon": "Open links in Mastodon" + }, + "boring_zone": { + "title": "The Boring Zone", + "account_settings": "Account Settings", + "terms": "Terms of Service", + "privacy": "Privacy Policy" + }, + "spicy_zone": { + "title": "The Spicy Zone", + "clear": "Clear Media Cache", + "signout": "Sign Out" + } + }, + "footer": { + "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + }, + "keyboard": { + "close_settings_window": "Close Settings Window" + } + }, + "report": { + "title_report": "Report", + "title": "Report %s", + "step1": "Step 1 of 2", + "step2": "Step 2 of 2", + "content1": "Are there any other posts you’d like to add to the report?", + "content2": "Is there anything the moderators should know about this report?", + "report_sent_title": "Thanks for reporting, we’ll look into this.", + "send": "Send Report", + "skip_to_send": "Send without comment", + "text_placeholder": "Type or paste additional comments", + "reported": "REPORTED", + "step_one": { + "step_1_of_4": "Step 1 of 4", + "whats_wrong_with_this_post": "What's wrong with this post?", + "whats_wrong_with_this_account": "What's wrong with this account?", + "whats_wrong_with_this_username": "What's wrong with %s?", + "select_the_best_match": "Select the best match", + "i_dont_like_it": "I don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "it_violates_server_rules": "It violates server rules", + "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "its_something_else": "It’s something else", + "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + }, + "step_two": { + "step_2_of_4": "Step 2 of 4", + "which_rules_are_being_violated": "Which rules are being violated?", + "select_all_that_apply": "Select all that apply", + "i_just_don’t_like_it": "I just don’t like it" + }, + "step_three": { + "step_3_of_4": "Step 3 of 4", + "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", + "select_all_that_apply": "Select all that apply" + }, + "step_four": { + "step_4_of_4": "Step 4 of 4", + "is_there_anything_else_we_should_know": "Is there anything else we should know?" + }, + "step_final": { + "dont_want_to_see_this": "Don’t want to see this?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "unfollow": "Unfollow", + "unfollowed": "Unfollowed", + "unfollow_user": "Unfollow %s", + "mute_user": "Mute %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "block_user": "Block %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } + }, + "preview": { + "keyboard": { + "close_preview": "Close Preview", + "show_next": "Show Next", + "show_previous": "Show Previous" + } + }, + "account_list": { + "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", + "dismiss_account_switcher": "Dismiss Account Switcher", + "add_account": "Add Account" + }, + "wizard": { + "new_in_mastodon": "New in Mastodon", + "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", + "accessibility_hint": "Double tap to dismiss this wizard" + }, + "bookmark": { + "title": "Bookmarks" + } + } +} From 489365730bdea33dcaa82a56d93dcbb255ead2ca Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 05:28:39 +0100 Subject: [PATCH 103/733] New translations ios-infoPlist.json (Aragonese) --- .../StringsConvertor/input/an.lproj/ios-infoPlist.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json new file mode 100644 index 000000000..c6db73de0 --- /dev/null +++ b/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json @@ -0,0 +1,6 @@ +{ + "NSCameraUsageDescription": "Used to take photo for post status", + "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NewPostShortcutItemTitle": "New Post", + "SearchShortcutItemTitle": "Search" +} From 4c9406b254246ddd9cae87e30ddb79f1e004c038 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 05:28:40 +0100 Subject: [PATCH 104/733] New translations Localizable.stringsdict (Aragonese) --- .../input/an.lproj/Localizable.stringsdict | 465 ++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict diff --git a/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict new file mode 100644 index 000000000..788eb95fc --- /dev/null +++ b/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict @@ -0,0 +1,465 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 unread notification + other + %ld unread notifications + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + Input limit exceeds %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + other + %ld characters + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + Input limit remains %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + other + %ld characters + + + a11y.plural.count.characters_left + + NSStringLocalizedFormatKey + %#@character_count@ left + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + other + %ld characters + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + post + other + posts + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 post + other + %ld posts + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 favorite + other + %ld favorites + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reblog + other + %ld reblogs + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reply + other + %ld replies + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 vote + other + %ld votes + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 voter + other + %ld voters + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 people talking + other + %ld people talking + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 following + other + %ld following + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 follower + other + %ld followers + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 year left + other + %ld years left + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 months left + other + %ld months left + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 day left + other + %ld days left + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 hour left + other + %ld hours left + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 minute left + other + %ld minutes left + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 second left + other + %ld seconds left + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1y ago + other + %ldy ago + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1M ago + other + %ldM ago + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1d ago + other + %ldd ago + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1h ago + other + %ldh ago + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1m ago + other + %ldm ago + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1s ago + other + %lds ago + + + + From 5f1aa4daaf1082899f1a1e55248b725572d2de1d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 05:28:41 +0100 Subject: [PATCH 105/733] New translations Intents.strings (Aragonese) --- .../Intents/input/an.lproj/Intents.strings | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings new file mode 100644 index 000000000..6877490ba --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Post on Mastodon"; + +"751xkl" = "Text Content"; + +"CsR7G2" = "Post on Mastodon"; + +"HZSGTr" = "What content to post?"; + +"HdGikU" = "Posting failed"; + +"KDNTJ4" = "Failure Reason"; + +"RHxKOw" = "Send Post with text content"; + +"RxSqsb" = "Post"; + +"WCIR3D" = "Post ${content} on Mastodon"; + +"ZKJSNu" = "Post"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Visibility"; + +"Zo4jgJ" = "Post Visibility"; + +"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; + +"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; + +"ayoYEb-dYQ5NN" = "${content}, Public"; + +"ayoYEb-ehFLjY" = "${content}, Followers Only"; + +"dUyuGg" = "Post on Mastodon"; + +"dYQ5NN" = "Public"; + +"ehFLjY" = "Followers Only"; + +"gfePDu" = "Posting failed. ${failureReason}"; + +"k7dbKQ" = "Post was sent successfully."; + +"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; + +"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Post was sent successfully. "; From b77182b21fc13dd163d388ad0d7dfb123942b901 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 05:28:42 +0100 Subject: [PATCH 106/733] New translations Intents.stringsdict (Aragonese) --- .../input/an.lproj/Intents.stringsdict | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict new file mode 100644 index 000000000..18422c772 --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict @@ -0,0 +1,38 @@ + + + + + There are ${count} options matching ‘${content}’. - 2 + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${content}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 option + other + %ld options + + + There are ${count} options matching ‘${visibility}’. + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${visibility}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 option + other + %ld options + + + + From 2314646d980092f07bd8dae00856638d5b4ac517 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 21 Nov 2022 11:27:14 +0100 Subject: [PATCH 107/733] fix: Always allow to continue when reporting a post if at least one is selected --- .../Report/ReportStatus/ReportStatusViewController.swift | 1 + .../Scene/Report/ReportStatus/ReportStatusViewModel.swift | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index 6f934e13d..f56af1f1e 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -59,6 +59,7 @@ class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewC let navigationActionView = NavigationActionView() navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color navigationActionView.backButton.setTitle(L10n.Common.Controls.Actions.skip, for: .normal) + navigationActionView.hidesBackButton = true return navigationActionView }() diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift index 5b80a9f3a..c1c79af48 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift @@ -71,9 +71,7 @@ class ReportStatusViewModel { } $selectStatuses - .map { statuses -> Bool in - return status == nil ? !statuses.isEmpty : statuses.count > 1 - } + .map { !$0.isEmpty } .assign(to: &$isNextButtonEnabled) } From 8d9e6ca8746ad263ef87f343db5b0dbe016487c8 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 21 Nov 2022 11:31:57 +0100 Subject: [PATCH 108/733] chore: Remove back button title --- .../Scene/Report/ReportStatus/ReportStatusViewController.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index f56af1f1e..02c3ccecb 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -58,7 +58,6 @@ class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewC let navigationActionView: NavigationActionView = { let navigationActionView = NavigationActionView() navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color - navigationActionView.backButton.setTitle(L10n.Common.Controls.Actions.skip, for: .normal) navigationActionView.hidesBackButton = true return navigationActionView }() From 9ffed8f3198a498671db85aaf075e039ad3818e7 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 21 Nov 2022 11:53:26 +0100 Subject: [PATCH 109/733] Revert "chore: Remove back button title" This reverts commit 8d9e6ca8746ad263ef87f343db5b0dbe016487c8. --- .../Scene/Report/ReportStatus/ReportStatusViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index 02c3ccecb..f56af1f1e 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -58,6 +58,7 @@ class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewC let navigationActionView: NavigationActionView = { let navigationActionView = NavigationActionView() navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color + navigationActionView.backButton.setTitle(L10n.Common.Controls.Actions.skip, for: .normal) navigationActionView.hidesBackButton = true return navigationActionView }() From 8f28999a937c35a0f929beae7445305d60b8b98b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 21 Nov 2022 11:57:02 +0100 Subject: [PATCH 110/733] chore: Only hide skip button if post has been selected --- .../Report/ReportStatus/ReportStatusViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index f56af1f1e..10e1ec3cd 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -59,7 +59,6 @@ class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewC let navigationActionView = NavigationActionView() navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color navigationActionView.backButton.setTitle(L10n.Common.Controls.Actions.skip, for: .normal) - navigationActionView.hidesBackButton = true return navigationActionView }() @@ -124,6 +123,10 @@ extension ReportStatusViewController { .assign(to: \.isEnabled, on: navigationActionView.nextButton) .store(in: &disposeBag) + if !viewModel.selectStatuses.isEmpty { + navigationActionView.hidesBackButton = true + } + navigationActionView.backButton.addTarget(self, action: #selector(ReportStatusViewController.skipButtonDidPressed(_:)), for: .touchUpInside) navigationActionView.nextButton.addTarget(self, action: #selector(ReportStatusViewController.nextButtonDidPressed(_:)), for: .touchUpInside) } From 788bdb14f8673fae67b0c2f15a8ce7dc92ce42a0 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 21 Nov 2022 08:40:04 -0500 Subject: [PATCH 111/733] Remove duplicate timestamps --- .../MastodonUI/View/Content/NotificationView+ViewModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index 64b120ec9..f29b0e6fd 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -108,6 +108,7 @@ extension NotificationView.ViewModel { .map { timestamp, _ in timestamp?.localizedTimeAgoSinceNow ?? "" } + .removeDuplicates() formattedTimestamp .sink { timestamp in From 228a9a1798e7e3ddb1b5e2b025553e122af22162 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 21 Nov 2022 08:46:49 -0500 Subject: [PATCH 112/733] Revert auto-formatter changes to file --- MastodonSDK/Package.resolved | 492 +++++++++--------- .../Content/NotificationView+ViewModel.swift | 53 +- 2 files changed, 281 insertions(+), 264 deletions(-) diff --git a/MastodonSDK/Package.resolved b/MastodonSDK/Package.resolved index 06843faa3..4a4fa51de 100644 --- a/MastodonSDK/Package.resolved +++ b/MastodonSDK/Package.resolved @@ -1,241 +1,257 @@ { - "object": { - "pins": [ - { - "package": "Alamofire", - "repositoryURL": "https://github.com/Alamofire/Alamofire.git", - "state": { - "branch": null, - "revision": "8dd85aee02e39dd280c75eef88ffdb86eed4b07b", - "version": "5.6.2" - } - }, - { - "package": "AlamofireImage", - "repositoryURL": "https://github.com/Alamofire/AlamofireImage.git", - "state": { - "branch": null, - "revision": "98cbb00ce0ec5fc8e52a5b50a6bfc08d3e5aee10", - "version": "4.2.0" - } - }, - { - "package": "CommonOSLog", - "repositoryURL": "https://github.com/MainasuK/CommonOSLog", - "state": { - "branch": null, - "revision": "c121624a30698e9886efe38aebb36ff51c01b6c2", - "version": "0.1.1" - } - }, - { - "package": "FaviconFinder", - "repositoryURL": "https://github.com/will-lumley/FaviconFinder.git", - "state": { - "branch": null, - "revision": "1f74844f77f79b95c0bb0130b3a87d4f340e6d3a", - "version": "3.3.0" - } - }, - { - "package": "FLAnimatedImage", - "repositoryURL": "https://github.com/Flipboard/FLAnimatedImage.git", - "state": { - "branch": null, - "revision": "d4f07b6f164d53c1212c3e54d6460738b1981e9f", - "version": "1.0.17" - } - }, - { - "package": "FPSIndicator", - "repositoryURL": "https://github.com/MainasuK/FPSIndicator.git", - "state": { - "branch": null, - "revision": "e4a5067ccd5293b024c767f09e51056afd4a4796", - "version": "1.1.0" - } - }, - { - "package": "Fuzi", - "repositoryURL": "https://github.com/cezheng/Fuzi.git", - "state": { - "branch": null, - "revision": "f08c8323da21e985f3772610753bcfc652c2103f", - "version": "3.1.3" - } - }, - { - "package": "KeychainAccess", - "repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git", - "state": { - "branch": null, - "revision": "84e546727d66f1adc5439debad16270d0fdd04e7", - "version": "4.2.2" - } - }, - { - "package": "MetaTextKit", - "repositoryURL": "https://github.com/TwidereProject/MetaTextKit.git", - "state": { - "branch": null, - "revision": "dcd5255d6930c2fab408dc8562c577547e477624", - "version": "2.2.5" - } - }, - { - "package": "Nuke", - "repositoryURL": "https://github.com/kean/Nuke.git", - "state": { - "branch": null, - "revision": "a002b7fd786f2df2ed4333fe73a9727499fd9d97", - "version": "10.11.2" - } - }, - { - "package": "NukeFLAnimatedImagePlugin", - "repositoryURL": "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", - "state": { - "branch": null, - "revision": "b59c346a7d536336db3b0f12c72c6e53ee709e16", - "version": "8.0.0" - } - }, - { - "package": "Pageboy", - "repositoryURL": "https://github.com/uias/Pageboy", - "state": { - "branch": null, - "revision": "af8fa81788b893205e1ff42ddd88c5b0b315d7c5", - "version": "3.7.0" - } - }, - { - "package": "PanModal", - "repositoryURL": "https://github.com/slackhq/PanModal.git", - "state": { - "branch": null, - "revision": "b012aecb6b67a8e46369227f893c12544846613f", - "version": "1.2.7" - } - }, - { - "package": "SDWebImage", - "repositoryURL": "https://github.com/SDWebImage/SDWebImage.git", - "state": { - "branch": null, - "revision": "9248fe561a2a153916fb9597e3af4434784c6d32", - "version": "5.13.4" - } - }, - { - "package": "swift-collections", - "repositoryURL": "https://github.com/apple/swift-collections.git", - "state": { - "branch": null, - "revision": "f504716c27d2e5d4144fa4794b12129301d17729", - "version": "1.0.3" - } - }, - { - "package": "swift-nio", - "repositoryURL": "https://github.com/apple/swift-nio.git", - "state": { - "branch": null, - "revision": "546610d52b19be3e19935e0880bb06b9c03f5cef", - "version": "1.14.4" - } - }, - { - "package": "swift-nio-zlib-support", - "repositoryURL": "https://github.com/apple/swift-nio-zlib-support.git", - "state": { - "branch": null, - "revision": "37760e9a52030bb9011972c5213c3350fa9d41fd", - "version": "1.0.0" - } - }, - { - "package": "SwiftSoup", - "repositoryURL": "https://github.com/scinfu/SwiftSoup.git", - "state": { - "branch": null, - "revision": "6778575285177365cbad3e5b8a72f2a20583cfec", - "version": "2.4.3" - } - }, - { - "package": "Introspect", - "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git", - "state": { - "branch": null, - "revision": "f2616860a41f9d9932da412a8978fec79c06fe24", - "version": "0.1.4" - } - }, - { - "package": "SwiftyJSON", - "repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON.git", - "state": { - "branch": null, - "revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07", - "version": "5.0.1" - } - }, - { - "package": "TabBarPager", - "repositoryURL": "https://github.com/TwidereProject/TabBarPager.git", - "state": { - "branch": null, - "revision": "488aa66d157a648901b61721212c0dec23d27ee5", - "version": "0.1.0" - } - }, - { - "package": "Tabman", - "repositoryURL": "https://github.com/uias/Tabman", - "state": { - "branch": null, - "revision": "4a4f7c755b875ffd4f9ef10d67a67883669d2465", - "version": "2.13.0" - } - }, - { - "package": "ThirdPartyMailer", - "repositoryURL": "https://github.com/vtourraine/ThirdPartyMailer.git", - "state": { - "branch": null, - "revision": "44c1cfaa6969963f22691aa67f88a69e3b6d651f", - "version": "2.1.0" - } - }, - { - "package": "TOCropViewController", - "repositoryURL": "https://github.com/TimOliver/TOCropViewController.git", - "state": { - "branch": null, - "revision": "d0470491f56e734731bbf77991944c0dfdee3e0e", - "version": "2.6.1" - } - }, - { - "package": "UIHostingConfigurationBackport", - "repositoryURL": "https://github.com/woxtu/UIHostingConfigurationBackport.git", - "state": { - "branch": null, - "revision": "6091f2d38faa4b24fc2ca0389c651e2f666624a3", - "version": "0.1.0" - } - }, - { - "package": "UITextView+Placeholder", - "repositoryURL": "https://github.com/MainasuK/UITextView-Placeholder.git", - "state": { - "branch": null, - "revision": "20f513ded04a040cdf5467f0891849b1763ede3b", - "version": "1.4.1" - } + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "8dd85aee02e39dd280c75eef88ffdb86eed4b07b", + "version" : "5.6.2" } - ] - }, - "version": 1 + }, + { + "identity" : "alamofireimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/AlamofireImage.git", + "state" : { + "revision" : "98cbb00ce0ec5fc8e52a5b50a6bfc08d3e5aee10", + "version" : "4.2.0" + } + }, + { + "identity" : "commonoslog", + "kind" : "remoteSourceControl", + "location" : "https://github.com/MainasuK/CommonOSLog", + "state" : { + "revision" : "c121624a30698e9886efe38aebb36ff51c01b6c2", + "version" : "0.1.1" + } + }, + { + "identity" : "faviconfinder", + "kind" : "remoteSourceControl", + "location" : "https://github.com/will-lumley/FaviconFinder.git", + "state" : { + "revision" : "1f74844f77f79b95c0bb0130b3a87d4f340e6d3a", + "version" : "3.3.0" + } + }, + { + "identity" : "flanimatedimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flipboard/FLAnimatedImage.git", + "state" : { + "revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f", + "version" : "1.0.17" + } + }, + { + "identity" : "fpsindicator", + "kind" : "remoteSourceControl", + "location" : "https://github.com/MainasuK/FPSIndicator.git", + "state" : { + "revision" : "e4a5067ccd5293b024c767f09e51056afd4a4796", + "version" : "1.1.0" + } + }, + { + "identity" : "fuzi", + "kind" : "remoteSourceControl", + "location" : "https://github.com/cezheng/Fuzi.git", + "state" : { + "revision" : "f08c8323da21e985f3772610753bcfc652c2103f", + "version" : "3.1.3" + } + }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state" : { + "revision" : "84e546727d66f1adc5439debad16270d0fdd04e7", + "version" : "4.2.2" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "44e891bdb61426a95e31492a67c7c0dfad1f87c5", + "version" : "7.4.1" + } + }, + { + "identity" : "metatextkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/TwidereProject/MetaTextKit.git", + "state" : { + "revision" : "dcd5255d6930c2fab408dc8562c577547e477624", + "version" : "2.2.5" + } + }, + { + "identity" : "nextlevelsessionexporter", + "kind" : "remoteSourceControl", + "location" : "https://github.com/NextLevel/NextLevelSessionExporter.git", + "state" : { + "revision" : "b6c0cce1aa37fe1547d694f958fac3c3524b74da", + "version" : "0.4.6" + } + }, + { + "identity" : "nuke", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kean/Nuke.git", + "state" : { + "revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97", + "version" : "10.11.2" + } + }, + { + "identity" : "nuke-flanimatedimage-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", + "state" : { + "revision" : "b59c346a7d536336db3b0f12c72c6e53ee709e16", + "version" : "8.0.0" + } + }, + { + "identity" : "pageboy", + "kind" : "remoteSourceControl", + "location" : "https://github.com/uias/Pageboy", + "state" : { + "revision" : "af8fa81788b893205e1ff42ddd88c5b0b315d7c5", + "version" : "3.7.0" + } + }, + { + "identity" : "panmodal", + "kind" : "remoteSourceControl", + "location" : "https://github.com/slackhq/PanModal.git", + "state" : { + "revision" : "b012aecb6b67a8e46369227f893c12544846613f", + "version" : "1.2.7" + } + }, + { + "identity" : "sdwebimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SDWebImage/SDWebImage.git", + "state" : { + "revision" : "9248fe561a2a153916fb9597e3af4434784c6d32", + "version" : "5.13.4" + } + }, + { + "identity" : "stripes", + "kind" : "remoteSourceControl", + "location" : "https://github.com/eneko/Stripes.git", + "state" : { + "revision" : "d533fd44b8043a3abbf523e733599173d6f98c11", + "version" : "0.2.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "f504716c27d2e5d4144fa4794b12129301d17729", + "version" : "1.0.3" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "546610d52b19be3e19935e0880bb06b9c03f5cef", + "version" : "1.14.4" + } + }, + { + "identity" : "swift-nio-zlib-support", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-zlib-support.git", + "state" : { + "revision" : "37760e9a52030bb9011972c5213c3350fa9d41fd", + "version" : "1.0.0" + } + }, + { + "identity" : "swiftsoup", + "kind" : "remoteSourceControl", + "location" : "https://github.com/scinfu/SwiftSoup.git", + "state" : { + "revision" : "6778575285177365cbad3e5b8a72f2a20583cfec", + "version" : "2.4.3" + } + }, + { + "identity" : "swiftui-introspect", + "kind" : "remoteSourceControl", + "location" : "https://github.com/siteline/SwiftUI-Introspect.git", + "state" : { + "revision" : "f2616860a41f9d9932da412a8978fec79c06fe24", + "version" : "0.1.4" + } + }, + { + "identity" : "tabbarpager", + "kind" : "remoteSourceControl", + "location" : "https://github.com/TwidereProject/TabBarPager.git", + "state" : { + "revision" : "488aa66d157a648901b61721212c0dec23d27ee5", + "version" : "0.1.0" + } + }, + { + "identity" : "tabman", + "kind" : "remoteSourceControl", + "location" : "https://github.com/uias/Tabman", + "state" : { + "revision" : "4a4f7c755b875ffd4f9ef10d67a67883669d2465", + "version" : "2.13.0" + } + }, + { + "identity" : "thirdpartymailer", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vtourraine/ThirdPartyMailer.git", + "state" : { + "revision" : "44c1cfaa6969963f22691aa67f88a69e3b6d651f", + "version" : "2.1.0" + } + }, + { + "identity" : "tocropviewcontroller", + "kind" : "remoteSourceControl", + "location" : "https://github.com/TimOliver/TOCropViewController.git", + "state" : { + "revision" : "d0470491f56e734731bbf77991944c0dfdee3e0e", + "version" : "2.6.1" + } + }, + { + "identity" : "uihostingconfigurationbackport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/woxtu/UIHostingConfigurationBackport.git", + "state" : { + "revision" : "6091f2d38faa4b24fc2ca0389c651e2f666624a3", + "version" : "0.1.0" + } + }, + { + "identity" : "uitextview-placeholder", + "kind" : "remoteSourceControl", + "location" : "https://github.com/MainasuK/UITextView-Placeholder.git", + "state" : { + "revision" : "20f513ded04a040cdf5467f0891849b1763ede3b", + "version" : "1.4.1" + } + } + ], + "version" : 2 } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index f29b0e6fd..714cf676d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -1,29 +1,29 @@ // // NotificationView+ViewModel.swift -// +// // // Created by MainasuK on 2022-1-21. // -import Combine -import CoreData -import CoreDataStack -import MastodonAsset -import MastodonCore -import MastodonExtension -import MastodonLocalization -import MastodonSDK -import Meta import os.log import UIKit +import Combine +import Meta +import MastodonSDK +import MastodonAsset +import MastodonLocalization +import MastodonExtension +import MastodonCore +import CoreData +import CoreDataStack -public extension NotificationView { - final class ViewModel: ObservableObject { +extension NotificationView { + public final class ViewModel: ObservableObject { public var disposeBag = Set() public var objects = Set() let logger = Logger(subsystem: "NotificationView", category: "ViewModel") - + @Published public var authContext: AuthContext? @Published public var type: MastodonNotificationType? @@ -33,16 +33,16 @@ public extension NotificationView { @Published public var authorAvatarImageURL: URL? @Published public var authorName: MetaContent? @Published public var authorUsername: String? - + @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false - + @Published public var timestamp: Date? - + @Published public var followRequestState = MastodonFollowRequestState(state: .none) @Published public var transientFollowRequestState = MastodonFollowRequestState(state: .none) - + let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common) .autoconnect() .share() @@ -63,7 +63,7 @@ extension NotificationView.ViewModel { .assign(to: \.authContext, on: notificationView.quoteStatusView.viewModel) .store(in: &disposeBag) } - + private func bindAuthor(notificationView: NotificationView) { // avatar Publishers.CombineLatest( @@ -137,7 +137,7 @@ extension NotificationView.ViewModel { notificationView.accessibilityLabel = [ "\(name?.string ?? "") \(type?.string ?? "")", username.map { "@\($0)" } ?? "", - timestamp, + timestamp ].joined(separator: ", ") if !notificationView.statusView.isHidden { notificationView.accessibilityLabel! += ", " + (notificationView.statusView.accessibilityLabel ?? "") @@ -197,7 +197,7 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) } - + private func bindAuthorMenu(notificationView: NotificationView) { Publishers.CombineLatest4( $authorName, @@ -210,24 +210,24 @@ extension NotificationView.ViewModel { notificationView.menuButton.menu = nil return } - + let menuContext = NotificationView.AuthorMenuContext( name: name, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself, - isBookmarking: false // no bookmark action display for notification item + isBookmarking: false // no bookmark action display for notification item ) let (menu, actions) = notificationView.setupAuthorMenu(menuContext: menuContext) notificationView.menuButton.menu = menu notificationView.authorActions = actions notificationView.menuButton.showsMenuAsPrimaryAction = true - + notificationView.menuButton.isHidden = menuContext.isMyself } .store(in: &disposeBag) } - + private func bindFollowRequest(notificationView: NotificationView) { Publishers.CombineLatest( $followRequestState, @@ -248,7 +248,7 @@ extension NotificationView.ViewModel { default: break } - + let state = transientFollowRequestState.state if state == .isAccepting { notificationView.acceptFollowRequestActivityIndicatorView.startAnimating() @@ -268,7 +268,7 @@ extension NotificationView.ViewModel { notificationView.rejectFollowRequestButton.tintColor = .black notificationView.rejectFollowRequestButton.setTitleColor(.black, for: .normal) } - + UIView.animate(withDuration: 0.3) { if state == .isAccept { notificationView.rejectFollowRequestButtonShadowBackgroundContainer.isHidden = true @@ -280,4 +280,5 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) } + } From 42febc93ea6fc81510744f8c3960eb43cf98124c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:02:57 +0100 Subject: [PATCH 113/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 0aed7bc15..17aa22109 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Domov", "search": "Iskanje", - "notification": "Obvestilo", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From 61c74a73b8a6b1eb817e67fea16799c2abc383e9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:02:58 +0100 Subject: [PATCH 114/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 7b1a3d08e..6eea8c3b2 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "หน้าแรก", "search": "ค้นหา", - "notification": "การแจ้งเตือน", + "notifications": "Notifications", "profile": "โปรไฟล์" }, "keyboard": { From 007b5727189f12da4dd11ce641993f17de26f3d8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:02:59 +0100 Subject: [PATCH 115/733] New translations app.json (Russian) --- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 25314102a..e71c41049 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Главная", "search": "Поиск", - "notification": "Уведомление", + "notifications": "Notifications", "profile": "Профиль" }, "keyboard": { From f6e68d9e87c418cf303362cd7eda201a6903d5d1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:00 +0100 Subject: [PATCH 116/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index c503c5186..f836f0349 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "主页", "search": "搜索", - "notification": "通知", + "notifications": "Notifications", "profile": "个人资料" }, "keyboard": { From 5dedc8601b8ad9951c66f9935b293bf503758330 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:02 +0100 Subject: [PATCH 117/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 3113ada74..c757b4979 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From 015db953b4ea109c3c9edeab7775a698f1977a5a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:03 +0100 Subject: [PATCH 118/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 15c7a612a..14bc718f1 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inicio", "search": "Busca", - "notification": "Notificación", + "notifications": "Notifications", "profile": "Perfil" }, "keyboard": { From 9d07806c6cd8c974aadf82f870a1be8c52ad00de Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:04 +0100 Subject: [PATCH 119/733] New translations app.json (Portuguese, Brazilian) --- Localization/StringsConvertor/input/pt-BR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 60d858235..770b42167 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Início", "search": "Buscar", - "notification": "Notificação", + "notifications": "Notifications", "profile": "Perfil" }, "keyboard": { From 1f5573ca092c8b9e2d7e57e4b2a61d6a77ee36f3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:05 +0100 Subject: [PATCH 120/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index f870bbbfc..98537abbe 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Beranda", "search": "Cari", - "notification": "Notifikasi", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From e79518f473cd85a6d38538191b13c9554c1f034c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:07 +0100 Subject: [PATCH 121/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 5be543f98..e87424de8 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Principal", "search": "Buscar", - "notification": "Notificación", + "notifications": "Notifications", "profile": "Perfil" }, "keyboard": { From f5e5d9646acaf68cd0544053bbf8ef223e25533b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:08 +0100 Subject: [PATCH 122/733] New translations app.json (Latvian) --- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 1ca18400b..c978536c7 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Sākums", "search": "Meklēšana", - "notification": "Paziņojums", + "notifications": "Notifications", "profile": "Profils" }, "keyboard": { From 619aee4fbb69b440dcb5e170cd537f86200654e2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:09 +0100 Subject: [PATCH 123/733] New translations app.json (Dutch) --- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 1df7f51aa..404034edc 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Start", "search": "Zoek", - "notification": "Melding", + "notifications": "Notifications", "profile": "Profiel" }, "keyboard": { From 00a245ee107e6df129fdcc8669efe31c3525e95c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:10 +0100 Subject: [PATCH 124/733] New translations app.json (Hindi) --- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index f9414b6c0..8a90d73af 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From 1d9992bf905a9494c0104057d615773182a42657 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:12 +0100 Subject: [PATCH 125/733] New translations app.json (English, United States) --- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 3113ada74..c757b4979 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From 6f64ff8cb8a657eb59532686942ac12ace65ec0e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:13 +0100 Subject: [PATCH 126/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 3cab04697..898934eb3 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Hafan", "search": "Chwilio", - "notification": "Hysbysiad", + "notifications": "Notifications", "profile": "Proffil" }, "keyboard": { From 6d5c0273c38541eeb88adbdd82927c343945d569 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:14 +0100 Subject: [PATCH 127/733] New translations app.json (Sinhala) --- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index a4542b9e9..6f48afe07 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From 5eee5a890813b075e073675e36f270ab0140eeac Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:15 +0100 Subject: [PATCH 128/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index eb553885c..d0c8bbb5c 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Serrûpel", "search": "Bigere", - "notification": "Agahdarî", + "notifications": "Notifications", "profile": "Profîl" }, "keyboard": { From e6178386ba4f7c83980f29cffa68096c8cbce958 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:17 +0100 Subject: [PATCH 129/733] New translations app.json (Sorani (Kurdish)) --- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 787bbea36..ff5a38e35 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "ماڵەوە", "search": "بگەڕێ", - "notification": "ئاگادارکردنەوەکان", + "notifications": "Notifications", "profile": "پرۆفایل" }, "keyboard": { From 5cb0060cb470451181f712ba55a198731712b03b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:18 +0100 Subject: [PATCH 130/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 191a670ed..fccba95bc 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Heim", "search": "Leita", - "notification": "Tilkynning", + "notifications": "Notifications", "profile": "Notandasnið" }, "keyboard": { From b2b6029c73deda7a1c50935dd68d6019a5abbab3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:19 +0100 Subject: [PATCH 131/733] New translations app.json (Burmese) --- Localization/StringsConvertor/input/my.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 1c3242165..a6d1c3f2b 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "အိမ်", "search": "ရှာဖွေရန်", - "notification": "သတိပေးချက်", + "notifications": "Notifications", "profile": "ကိုယ်ရေးမှတ်တမ်း" }, "keyboard": { From 0795c10ecd3b37bda9873c2bdadb4ab864a5ec88 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:21 +0100 Subject: [PATCH 132/733] New translations app.json (Portuguese) --- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 3113ada74..c757b4979 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From 42bb4caf9d5c527b64781fbb126524162d43acfc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:22 +0100 Subject: [PATCH 133/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 4f8d5f578..3ea037335 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "ホーム", "search": "検索", - "notification": "通知", + "notifications": "Notifications", "profile": "プロフィール" }, "keyboard": { From f34ffa0a6feeedc6d38d7c598bd5370db4264411 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:23 +0100 Subject: [PATCH 134/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index e2dfaad64..d0935d54a 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "首頁", "search": "搜尋", - "notification": "通知", + "notifications": "Notifications", "profile": "個人檔案" }, "keyboard": { From 91aa78b83b19cfcd2947303f65878db78a8e9b1e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:24 +0100 Subject: [PATCH 135/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 987f65cf4..513137936 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Головна", "search": "Пошук", - "notification": "Сповіщення", + "notifications": "Notifications", "profile": "Профіль" }, "keyboard": { From 4346df98807a3a72682343e9066e1623a409b669 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:25 +0100 Subject: [PATCH 136/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 963be39c9..88d93b2fa 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Bảng tin", "search": "Tìm kiếm", - "notification": "Thông báo", + "notifications": "Notifications", "profile": "Trang hồ sơ" }, "keyboard": { From 0c54b20e4a542e1a70bfc7f03bf1fc54aab23f12 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:27 +0100 Subject: [PATCH 137/733] New translations app.json (Kabyle) --- Localization/StringsConvertor/input/kab.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 62cea8780..2687e1dfd 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Agejdan", "search": "Nadi", - "notification": "Tilɣa", + "notifications": "Notifications", "profile": "Amaɣnu" }, "keyboard": { From 676f847220c4c9f97feb5e5853e43bbb650ec491 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:28 +0100 Subject: [PATCH 138/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 070386bf9..4cf5c3de5 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "홈", "search": "검색", - "notification": "알림", + "notifications": "Notifications", "profile": "프로필" }, "keyboard": { From fee64cf3664c830b1aa5bcf91048f41987d5d2aa Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:29 +0100 Subject: [PATCH 139/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 7951e1958..70f0cc422 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Hem", "search": "Sök", - "notification": "Notis", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From be4ce886470c214e3cc107ea4c70f79fa02a8ba5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:30 +0100 Subject: [PATCH 140/733] New translations app.json (French) --- Localization/StringsConvertor/input/fr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index fc8fd0e7a..b061fee34 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Accueil", "search": "Rechercher", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From 70b200fc2da2fe5b62f3a614bf99e2305e05ee8a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:32 +0100 Subject: [PATCH 141/733] New translations app.json (Turkish) --- Localization/StringsConvertor/input/tr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 3507d1f5c..dc3aadb9c 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Ana Sayfa", "search": "Arama", - "notification": "Bildirimler", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From 4ee57f5e9bf770c37218a295bdb9767a8376eb45 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:33 +0100 Subject: [PATCH 142/733] New translations app.json (Czech) --- Localization/StringsConvertor/input/cs.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 680eb01bb..318b404cf 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Domů", "search": "Hledat", - "notification": "Oznamování", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From 6be6879c4e9019d446e47af991dc7714aa56fd9a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:36 +0100 Subject: [PATCH 143/733] New translations app.json (Scottish Gaelic) --- Localization/StringsConvertor/input/gd.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 74666cb0c..25de9c917 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Dachaigh", "search": "Lorg", - "notification": "Brath", + "notifications": "Notifications", "profile": "Pròifil" }, "keyboard": { From 2846a25fb96d6df4213e76cc459a31feb5d61bcd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:37 +0100 Subject: [PATCH 144/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index f4f21762b..b34c515b5 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inizio", "search": "Cerca", - "notification": "Notifiche", + "notifications": "Notifications", "profile": "Profilo" }, "keyboard": { From a9bcd2b5422162bcbc7100af1111d99e2953cc91 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:39 +0100 Subject: [PATCH 145/733] New translations app.json (Romanian) --- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 75a77184c..b6e399f8b 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From f14a693b49fe3241eb039b868c9021ecf290327e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:40 +0100 Subject: [PATCH 146/733] New translations app.json (Spanish) --- Localization/StringsConvertor/input/es.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 1b90bfa10..cab7e70fb 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inicio", "search": "Buscar", - "notification": "Notificación", + "notifications": "Notifications", "profile": "Perfil" }, "keyboard": { From 99b727964112352daf3df4854e69c9c8a81c5c3b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:41 +0100 Subject: [PATCH 147/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index bf4bf454e..cec1b7cf3 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "الرَّئِيسَة", "search": "البَحث", - "notification": "الإشعارات", + "notifications": "Notifications", "profile": "المِلَفُّ التَّعريفِيّ" }, "keyboard": { From d3ef450484790169188a4a21cbea44ed2a70f5fc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:42 +0100 Subject: [PATCH 148/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 52bb67c77..fcec81a1c 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inici", "search": "Cerca", - "notification": "Notificació", + "notifications": "Notifications", "profile": "Perfil" }, "keyboard": { From 8beacab196193ec1ddb8fe2f74074b5b3e4b005c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:43 +0100 Subject: [PATCH 149/733] New translations app.json (Danish) --- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 3113ada74..c757b4979 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From a830dad79ff6c08bbe55f6890c1f5586f095bbde Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:44 +0100 Subject: [PATCH 150/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 65a315b5c..1b1a81e81 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Startseite", "search": "Suche", - "notification": "Benachrichtigungen", + "notifications": "Notifications", "profile": "Profil" }, "keyboard": { From 82a1652e9a5b0748d06bd9b407de09518b5d1343 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:46 +0100 Subject: [PATCH 151/733] New translations app.json (Basque) --- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index c52ffdbbf..4a50606a9 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Hasiera", "search": "Bilatu", - "notification": "Jakinarazpena", + "notifications": "Notifications", "profile": "Profila" }, "keyboard": { From c80b9312c6336650e4839f53a7d4f637ee507d3d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:47 +0100 Subject: [PATCH 152/733] New translations app.json (Finnish) --- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 7dafe7fd1..c575a9144 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Koti", "search": "Haku", - "notification": "Ilmoitus", + "notifications": "Notifications", "profile": "Profiili" }, "keyboard": { From 28ad56f6e3b910ed34f5ffda8b813bcfcdc0cca0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 17:03:48 +0100 Subject: [PATCH 153/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 3113ada74..c757b4979 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Home", "search": "Search", - "notification": "Notification", + "notifications": "Notifications", "profile": "Profile" }, "keyboard": { From a4283a8378bc9c59cff8cbd2ada06254cd26886d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 18:07:42 +0100 Subject: [PATCH 154/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 70f0cc422..c19d4c628 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Hem", "search": "Sök", - "notifications": "Notifications", + "notifications": "Notiser", "profile": "Profil" }, "keyboard": { From 6273a8ab2fc3c88b94afc395c73c6622c3c8b927 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 18:07:44 +0100 Subject: [PATCH 155/733] New translations app.json (Arabic) --- .../StringsConvertor/input/ar.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index cec1b7cf3..2a3c408b7 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "الرَّئِيسَة", "search": "البَحث", - "notifications": "Notifications", + "notifications": "الإشعارات", "profile": "المِلَفُّ التَّعريفِيّ" }, "keyboard": { @@ -219,15 +219,15 @@ "log_in": "تسجيلُ الدخول" }, "login": { - "title": "Welcome back", + "title": "مَرحَبًا بِكَ مُجَدَّدًا", "subtitle": "Log you in on the server you created your account on.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "أدخِل عُنوانَ URL أو اِبحَث عَنِ الخادِمِ الخاصّ بِك" } }, "server_picker": { "title": "اِختر خادِم،\nأيًّا مِنهُم.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "اِختر خادمًا بناءً على منطقتك، اِهتماماتك أو يُمكنك حتى اِختيارُ مجتمعٍ ذِي غرضٍ عام. بِإمكانِكَ الدردشة مع أي شخص على مَاستودُون، بغض النظر عن الخادم الخاصة بك.", "button": { "category": { "all": "الكُل", @@ -254,7 +254,7 @@ "category": "الفئة" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "اِبحث عَن مُجتَمَعَات أو أدخِل عُنوانَ URL" }, "empty_state": { "finding_servers": "يجري إيجاد خوادم متوفِّرَة...", @@ -427,7 +427,7 @@ "enable_content_warning": "تفعيل تحذير المُحتَوى", "disable_content_warning": "تعطيل تحذير المُحتَوى", "post_visibility_menu": "قائمة ظهور المنشور", - "post_options": "Post Options", + "post_options": "خياراتُ المَنشور", "posting_as": "نَشر كَـ %s" }, "keyboard": { From 2053f2f8ec0852489a1df0d0d55db4973e35eedb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 18:07:46 +0100 Subject: [PATCH 156/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index fcec81a1c..91289f461 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inici", "search": "Cerca", - "notifications": "Notifications", + "notifications": "Notificacions", "profile": "Perfil" }, "keyboard": { From e8eac512f338ec0db0236e6f197b1176e0557d53 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 18:07:47 +0100 Subject: [PATCH 157/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index b34c515b5..2cd40458e 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inizio", "search": "Cerca", - "notifications": "Notifications", + "notifications": "Notifiche", "profile": "Profilo" }, "keyboard": { From 5274889389c5ec8aba3ca26e820a9ce03c21ddbd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 19:36:12 +0100 Subject: [PATCH 158/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 17aa22109..f37d088a7 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Domov", "search": "Iskanje", - "notifications": "Notifications", + "notifications": "Obvestila", "profile": "Profil" }, "keyboard": { From 0ca8d5f42636459ac63e0bde0c414f70aa341ee1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 19:36:13 +0100 Subject: [PATCH 159/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 2a3c408b7..b12d26bad 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -75,7 +75,7 @@ "save_photo": "حفظ الصورة", "copy_photo": "نسخ الصورة", "sign_in": "تسجيلُ الدخول", - "sign_up": "Create account", + "sign_up": "إنشاءُ حِساب", "see_more": "عرض المزيد", "preview": "مُعاينة", "share": "المُشارك", From b68acd1d2134da819404bfc555bf6eada1528f91 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Nov 2022 19:36:14 +0100 Subject: [PATCH 160/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index e87424de8..cf2b521c2 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Principal", "search": "Buscar", - "notifications": "Notifications", + "notifications": "Notificaciones", "profile": "Perfil" }, "keyboard": { From 91425d03dcd252c0607b6ef9fb9b111cb06846a8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:24 +0100 Subject: [PATCH 161/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index d0935d54a..209beb2d8 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "首頁", "search": "搜尋", - "notifications": "Notifications", + "notifications": "通知", "profile": "個人檔案" }, "keyboard": { From f845a134e897bf927ae1ecf7a64b0a57a762b1db Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:25 +0100 Subject: [PATCH 162/733] New translations app.json (Aragonese) --- .../StringsConvertor/input/an.lproj/app.json | 898 +++++++++--------- 1 file changed, 449 insertions(+), 449 deletions(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index c757b4979..9884430ce 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -2,726 +2,726 @@ "common": { "alerts": { "common": { - "please_try_again": "Please try again.", - "please_try_again_later": "Please try again later." + "please_try_again": "Per favor, torna a intentar-lo.", + "please_try_again_later": "Per favor, torna a intentar-lo mas enta debant." }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "Error en rechistrar-se" }, "server_error": { - "title": "Server Error" + "title": "Error d'o servidor" }, "vote_failure": { - "title": "Vote Failure", - "poll_ended": "The poll has ended" + "title": "Voto fallido", + "poll_ended": "La enquesta ha rematau" }, "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." + "title": "Descartar borrador", + "message": "Confirma pa descartar lo conteniu d'a publicación." }, "publish_post_failure": { - "title": "Publish Failure", - "message": "Failed to publish the post.\nPlease check your internet connection.", + "title": "Error de publicación", + "message": "No s'ha puesto publicar la publicación. Per favor, revise la suya connexión a internet.", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", - "more_than_one_video": "Cannot attach more than one video." + "video_attach_with_photo": "No puetz adchuntar un video a una publicación que ya contiene imachens.", + "more_than_one_video": "No puetz adchuntar mas d'un video." } }, "edit_profile_failure": { - "title": "Edit Profile Error", - "message": "Cannot edit profile. Please try again." + "title": "Error en a Edición d'o Perfil", + "message": "No s'ha puesto editar lo perfil. Per favor, intenta-lo de nuevo." }, "sign_out": { - "title": "Sign Out", - "message": "Are you sure you want to sign out?", - "confirm": "Sign Out" + "title": "Zarrar Sesión", + "message": "Yes seguro de que quiers zarrar la sesión?", + "confirm": "Zarrar Sesión" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", - "block_entire_domain": "Block Domain" + "title": "Yes realment seguro, de verdat, que quiers blocar %s a lo completo? En a mayoría d'os casos, uns pocos bloqueyos u silenciaus concretos son suficients y preferibles. No veyerás conteniu d'ixe dominio y totz los tuyos seguidores d'ixe dominio serán eliminaus.", + "block_entire_domain": "Blocar Dominio" }, "save_photo_failure": { - "title": "Save Photo Failure", - "message": "Please enable the photo library access permission to save the photo." + "title": "Error en Alzar Foto", + "message": "Per favor, activa lo permiso d'acceso a la biblioteca de fotos pa alzar la foto." }, "delete_post": { - "title": "Delete Post", - "message": "Are you sure you want to delete this post?" + "title": "Yes seguro de que quiers eliminar esta publicación?", + "message": "Yes seguro de que quiers borrar esta publicación?" }, "clean_cache": { - "title": "Clean Cache", - "message": "Successfully cleaned %s cache." + "title": "Limpiar Caché", + "message": "S'ha limpiau con exito %s de caché." } }, "controls": { "actions": { - "back": "Back", - "next": "Next", - "previous": "Previous", - "open": "Open", - "add": "Add", - "remove": "Remove", - "edit": "Edit", - "save": "Save", - "ok": "OK", - "done": "Done", - "confirm": "Confirm", - "continue": "Continue", - "compose": "Compose", - "cancel": "Cancel", - "discard": "Discard", - "try_again": "Try Again", - "take_photo": "Take Photo", - "save_photo": "Save Photo", - "copy_photo": "Copy Photo", - "sign_in": "Log in", - "sign_up": "Create account", - "see_more": "See More", - "preview": "Preview", - "share": "Share", - "share_user": "Share %s", - "share_post": "Share Post", - "open_in_safari": "Open in Safari", - "open_in_browser": "Open in Browser", - "find_people": "Find people to follow", - "manually_search": "Manually search instead", - "skip": "Skip", - "reply": "Reply", - "report_user": "Report %s", - "block_domain": "Block %s", - "unblock_domain": "Unblock %s", - "settings": "Settings", - "delete": "Delete" + "back": "Dezaga", + "next": "Siguient", + "previous": "Anterior", + "open": "Ubrir", + "add": "Anyadir", + "remove": "Eliminar", + "edit": "Editar", + "save": "Alzar", + "ok": "Acceptar", + "done": "Feito", + "confirm": "Confirmar", + "continue": "Continar", + "compose": "Redactar", + "cancel": "Cancelar", + "discard": "Descartar", + "try_again": "Intenta-lo de nuevo", + "take_photo": "Prener foto", + "save_photo": "Alzar foto", + "copy_photo": "Copiar foto", + "sign_in": "Iniciar sesión", + "sign_up": "Crear cuenta", + "see_more": "Veyer mas", + "preview": "Vista previa", + "share": "Compartir", + "share_user": "Compartir %s", + "share_post": "Compartir publicación", + "open_in_safari": "Ubrir en Safari", + "open_in_browser": "Ubrir en o navegador", + "find_people": "Troba chent a la quala seguir", + "manually_search": "Millor fer una busqueda manual", + "skip": "Omitir", + "reply": "Responder", + "report_user": "Reportar a %s", + "block_domain": "Blocar %s", + "unblock_domain": "Desbloquiar %s", + "settings": "Configuración", + "delete": "Borrar" }, "tabs": { - "home": "Home", - "search": "Search", - "notifications": "Notifications", - "profile": "Profile" + "home": "Inicio", + "search": "Buscar", + "notifications": "Notificacions", + "profile": "Perfil" }, "keyboard": { "common": { - "switch_to_tab": "Switch to %s", - "compose_new_post": "Compose New Post", - "show_favorites": "Show Favorites", - "open_settings": "Open Settings" + "switch_to_tab": "Cambiar a %s", + "compose_new_post": "Escribir Nueva Publicación", + "show_favorites": "Amostrar Favoritos", + "open_settings": "Ubrir Configuración" }, "timeline": { - "previous_status": "Previous Post", - "next_status": "Next Post", - "open_status": "Open Post", - "open_author_profile": "Open Author's Profile", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", - "toggle_reblog": "Toggle Reblog on Post", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", - "preview_image": "Preview Image" + "previous_status": "Publicación Anterior", + "next_status": "Siguient Publicación", + "open_status": "Ubrir Publicación", + "open_author_profile": "Ubrir Perfil de l'Autor", + "open_reblogger_profile": "Ubrir Perfil d'o Reblogueador", + "reply_status": "Responder Publicación", + "toggle_reblog": "Commutar lo Reblogueo en a Publicación", + "toggle_favorite": "Commutar la Marca de Favorito en a Publicación", + "toggle_content_warning": "Alternar l'Alvertencia de Conteniu", + "preview_image": "Previsualizar Imachen" }, "segmented_control": { - "previous_section": "Previous Section", - "next_section": "Next Section" + "previous_section": "Sección Anterior", + "next_section": "Siguient Sección" } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", - "show_post": "Show Post", - "show_user_profile": "Show user profile", - "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", + "user_reblogged": "%s lo reblogueó", + "user_replied_to": "En respuesta a %s", + "show_post": "Amostrar Publicación", + "show_user_profile": "Amostrar perfil de l'usuario", + "content_warning": "Alvertencia de Conteniu", + "sensitive_content": "Conteniu sensible", + "media_content_warning": "Preta en qualsequier puesto pa amostrar", + "tap_to_reveal": "Tocar pa revelar", "poll": { - "vote": "Vote", - "closed": "Closed" + "vote": "Vota", + "closed": "Zarrau" }, "meta_entity": { - "url": "Link: %s", + "url": "Vinclo: %s", "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "mention": "Amostrar lo perfil: %s", + "email": "Adreza de correu: %s" }, "actions": { - "reply": "Reply", - "reblog": "Reblog", - "unreblog": "Undo reblog", - "favorite": "Favorite", - "unfavorite": "Unfavorite", - "menu": "Menu", - "hide": "Hide", - "show_image": "Show image", - "show_gif": "Show GIF", - "show_video_player": "Show video player", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "reply": "Responder", + "reblog": "Rebloguear", + "unreblog": "Desfer reblogueo", + "favorite": "Favorito", + "unfavorite": "No favorito", + "menu": "Menú", + "hide": "Amagar", + "show_image": "Amostrar imachen", + "show_gif": "Amostrar GIF", + "show_video_player": "Amostrar reproductor de video", + "tap_then_hold_to_show_menu": "Toca, dimpués mantiene pa amostrar lo menú" }, "tag": { "url": "URL", - "mention": "Mention", - "link": "Link", - "hashtag": "Hashtag", - "email": "Email", + "mention": "Mención", + "link": "Vinclo", + "hashtag": "Etiqueta", + "email": "E-mail", "emoji": "Emoji" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "Totz pueden veyer este post pero no amostrar-lo en una linia de tiempo publica.", + "private": "Nomás los suyos seguidores pueden veyer este mensache.", + "private_from_me": "Nomás los míos seguidores pueden veyer este mensache.", + "direct": "Nomás l'usuario mencionau puede veyer este mensache." } }, "friendship": { - "follow": "Follow", - "following": "Following", - "request": "Request", - "pending": "Pending", - "block": "Block", - "block_user": "Block %s", - "block_domain": "Block %s", - "unblock": "Unblock", - "unblock_user": "Unblock %s", - "blocked": "Blocked", - "mute": "Mute", - "mute_user": "Mute %s", - "unmute": "Unmute", - "unmute_user": "Unmute %s", - "muted": "Muted", - "edit_info": "Edit Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "follow": "Seguir", + "following": "Seguindo", + "request": "Solicitut", + "pending": "Pendient", + "block": "Blocar", + "block_user": "Blocar a %s", + "block_domain": "Blocar a %s", + "unblock": "Desbloquiar", + "unblock_user": "Desbloquiar a %s", + "blocked": "Blocau", + "mute": "Silenciar", + "mute_user": "Silenciar a %s", + "unmute": "Desmutear", + "unmute_user": "Desmutear a %s", + "muted": "Silenciau", + "edit_info": "Editar Info", + "show_reblogs": "Amostrar los retuts", + "hide_reblogs": "Amagar los reblogs" }, "timeline": { - "filtered": "Filtered", + "filtered": "Filtrau", "timestamp": { - "now": "Now" + "now": "Agora" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", - "show_more_replies": "Show more replies" + "load_missing_posts": "Cargar publicacions faltantes", + "loading_missing_posts": "Cargando publicacions faltantes...", + "show_more_replies": "Amostrar mas respuestas" }, "header": { - "no_status_found": "No Post Found", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "no_status_found": "No s'ha trobau garra publicación", + "blocking_warning": "No puetz veyer lo perfil d'este usuario\n dica que lo desbloqueyes.\nLo tuyo perfil se veye asinas pa ell.", + "user_blocking_warning": "No puetz veyer lo perfil de %s\n dica que lo desbloqueyes.\nLo tuyo perfil se veye asinas pa ell.", + "blocked_warning": "No puetz veyer lo perfil d'este usuario\n dica que te desbloqueye.", + "user_blocked_warning": "No puetz veyer lo perfil de %s\n dica que te desbloqueye.", + "suspended_warning": "Este usuario ha estau suspendiu.", + "user_suspended_warning": "La cuenta de %s ha estau suspendida." } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", - "log_in": "Log In" + "slogan": "Los retz socials\nde nuevo en as tuyas mans.", + "get_started": "Empecipiar", + "log_in": "Encetar sesión" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "Bienveniu de nuevas", + "subtitle": "Dentrar en o servidor an que creyiés la cuenta.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Escribir la URL u buscar lo tuyo servidor" } }, "server_picker": { - "title": "Mastodon is made of users in different servers.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "title": "Tría un servidor,\nqualsequier servidor.", + "subtitle": "Tría un servidor basau en a tuya rechión, intereses u uno de proposito cheneral. Podrás seguir connectau con totz en Mastodon, independiement d'o servidor.", "button": { "category": { - "all": "All", - "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", - "food": "food", + "all": "Totas", + "all_accessiblity_description": "Categoría: Totas", + "academia": "academicos", + "activism": "activismo", + "food": "minchada", "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", + "games": "chuegos", + "general": "cheneral", + "journalism": "periodismo", "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "regional": "rechional", + "art": "arte", + "music": "mosica", + "tech": "tecnolochía" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "Veyer Menos", + "see_more": "Veyer Más" }, "label": { - "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "language": "IDIOMA", + "users": "USUARIOS", + "category": "CATEGORÍA" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Mirar comunidatz u escribir URL" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "finding_servers": "Trobando servidors disponibles...", + "bad_network": "Bella cosa ha iu malament en cargar los datos. Compreba la tuya connexión a Internet.", + "no_results": "Sin resultaus" } }, "register": { - "title": "Let’s get you set up on %s", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "title": "Deixa que te configuremos en %s", + "lets_get_you_set_up_on_domain": "Deixa que te configuremos en %s", "input": { "avatar": { - "delete": "Delete" + "delete": "Borrar" }, "username": { - "placeholder": "username", - "duplicate_prompt": "This username is taken." + "placeholder": "nombre d'usuario", + "duplicate_prompt": "Este nombre d'usuario ya ye en uso." }, "display_name": { - "placeholder": "display name" + "placeholder": "nombre a amostrar" }, "email": { - "placeholder": "email" + "placeholder": "correu electronico" }, "password": { - "placeholder": "password", - "require": "Your password needs at least:", - "character_limit": "8 characters", + "placeholder": "clau", + "require": "La tuya clau ha de contener como minimo:", + "character_limit": "8 caracters", "accessibility": { - "checked": "checked", - "unchecked": "unchecked" + "checked": "marcau", + "unchecked": "sin marcar" }, - "hint": "Your password needs at least eight characters" + "hint": "La tuya clau ameneste tener a lo menos ueito caracters" }, "invite": { - "registration_user_invite_request": "Why do you want to join?" + "registration_user_invite_request": "Per qué quiers unir-te?" } }, "error": { "item": { - "username": "Username", - "email": "Email", - "password": "Password", - "agreement": "Agreement", - "locale": "Locale", - "reason": "Reason" + "username": "Nombre d'usuario", + "email": "Correu electronico", + "password": "Clau", + "agreement": "Acceptación", + "locale": "Idioma", + "reason": "Motivo" }, "reason": { - "blocked": "%s contains a disallowed email provider", - "unreachable": "%s does not seem to exist", - "taken": "%s is already in use", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", - "blank": "%s is required", - "invalid": "%s is invalid", - "too_long": "%s is too long", - "too_short": "%s is too short", - "inclusion": "%s is not a supported value" + "blocked": "%s contiene un furnidor de correu no permitiu", + "unreachable": "%s pareixe no existir", + "taken": "%s ya ye en uso", + "reserved": "%s ye una parola clau reservada", + "accepted": "%s ha d'estar acceptau", + "blank": "Se requiere %s", + "invalid": "%s no ye valido", + "too_long": "%s ye masiau largo", + "too_short": "%s ye masiau tallo", + "inclusion": "%s no ye una valor admitida" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", - "password_too_short": "Password is too short (must be at least 8 characters)" + "username_invalid": "Lo nombre d'usuario solo puede contener caracters alfanumericos y guións baixos", + "username_too_long": "Lo nombre d'usuario ye masiau largo (no puede tener mas de 30 caracters)", + "email_invalid": "Esta no ye una adreza de correu electronico valida", + "password_too_short": "La clau ye masiau curta (ha de tener a lo menos 8 caracters)" } } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "title": "Qualques reglas basicas.", + "subtitle": "Estas reglas son establidas per los administradors de %s.", + "prompt": "Si continas serás sucheto a los termins de servicio y la politica de privacidat de %s.", + "terms_of_service": "termins d'o servicio", + "privacy_policy": "politica de privacidat", "button": { - "confirm": "I Agree" + "confirm": "Accepto" } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "title": "Una zaguera coseta.", + "subtitle": "T'acabamos de ninviar un correu a %s, preta en o vinclo pa confirmar la tuya cuenta.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Toca lo vinclo que te ninviamos per correu electronico pa verificar la tuya cuenta", "button": { - "open_email_app": "Open Email App", - "resend": "Resend" + "open_email_app": "Ubrir Aplicación de Correu Electronico", + "resend": "Reninviar" }, "dont_receive_email": { - "title": "Check your email", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "title": "Revisa lo tuyo correu electronico", + "description": "Compreba que la tuya adreza de correu electronico sía correcta y revisa la carpeta de correu no deseyau si no l'has feito ya.", + "resend_email": "Tornar a Ninviar Correu Electronico" }, "open_email_app": { - "title": "Check your inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", - "mail": "Mail", - "open_email_client": "Open Email Client" + "title": "Revisa la tuya servilla de dentrada.", + "description": "T'acabamos de ninviar un correu electronico. Revisa la tuya carpeta de correu no deseyau si no l'has feito ya.", + "mail": "Correu", + "open_email_client": "Ubrir Client de Correu Electronico" } }, "home_timeline": { - "title": "Home", + "title": "Inicio", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "Sin Connexión", + "new_posts": "Veyer nuevas publicacions", + "published": "Publicau!", + "Publishing": "Publicación en curso...", "accessibility": { - "logo_label": "Logo Button", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_label": "Botón d'o logo", + "logo_hint": "Toca pa desplazar-te enta alto y toca de nuevo pa la localización anterior" } } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Troba Chent a la quala Seguir", + "follow_explain": "Quan sigas a belún veyerás las suyas publicacions en a tuya pachina d'inicio." }, "compose": { "title": { - "new_post": "New Post", - "new_reply": "New Reply" + "new_post": "Nueva Publicación", + "new_reply": "Nueva Respuesta" }, "media_selection": { - "camera": "Take Photo", - "photo_library": "Photo Library", - "browse": "Browse" + "camera": "Fer Foto", + "photo_library": "Galería de Fotos", + "browse": "Explorar" }, - "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", + "content_input_placeholder": "Escribe u apega lo que tiengas en mente", + "compose_action": "Publicar", + "replying_to_user": "en respuesta a %s", "attachment": { - "photo": "photo", + "photo": "foto", "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "attachment_broken": "Este %s ye roto y no puede\npuyar-se a Mastodon.", + "description_photo": "Describe la foto pa los usuarios con dificultat visual...", + "description_video": "Describe lo video pa los usuarios con dificultat visual...", + "load_failed": "Fallo de carga", + "upload_failed": "Fallo de carga", + "can_not_recognize_this_media_attachment": "No se puede reconocer este adchunto multimedia", + "attachment_too_large": "Adchunto masiau gran", + "compressing_state": "Comprimindo...", + "server_processing_state": "Lo servidor ye procesando..." }, "poll": { - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", - "three_days": "3 Days", - "seven_days": "7 Days", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "duration_time": "Duración: %s", + "thirty_minutes": "30 minutos", + "one_hour": "1 Hora", + "six_hours": "6 Horas", + "one_day": "1 Día", + "three_days": "3 Días", + "seven_days": "7 Días", + "option_number": "Opción %ld", + "the_poll_is_invalid": "La enquesta ye invalida", + "the_poll_has_empty_option": "La enquesta tiene opcions vuedas" }, "content_warning": { - "placeholder": "Write an accurate warning here..." + "placeholder": "Escribe una alvertencia precisa aquí..." }, "visibility": { - "public": "Public", - "unlisted": "Unlisted", - "private": "Followers only", - "direct": "Only people I mention" + "public": "Publica", + "unlisted": "Sin listar", + "private": "Solo seguidores", + "direct": "Solo la chent que yo menciono" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Espacio pa anyadir" }, "accessibility": { - "append_attachment": "Add Attachment", - "append_poll": "Add Poll", - "remove_poll": "Remove Poll", - "custom_emoji_picker": "Custom Emoji Picker", - "enable_content_warning": "Enable Content Warning", - "disable_content_warning": "Disable Content Warning", - "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "append_attachment": "Anyadir Adchunto", + "append_poll": "Anyadir Enqüesta", + "remove_poll": "Eliminar Enqüesta", + "custom_emoji_picker": "Selector de Emojis Personalizaus", + "enable_content_warning": "Activar Alvertencia de Conteniu", + "disable_content_warning": "Desactivar Alvertencia de Conteniu", + "post_visibility_menu": "Menú de Visibilidat d'a Publicación", + "post_options": "Opcions d'o tut", + "posting_as": "Publicando como %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", - "toggle_poll": "Toggle Poll", - "toggle_content_warning": "Toggle Content Warning", - "append_attachment_entry": "Add Attachment - %s", - "select_visibility_entry": "Select Visibility - %s" + "discard_post": "Descartar Publicación", + "publish_post": "Publicar", + "toggle_poll": "Commutar Enqüesta", + "toggle_content_warning": "Commutar Alvertencia de Conteniu", + "append_attachment_entry": "Anyadir Adchunto - %s", + "select_visibility_entry": "Triar Visibilidat - %s" } }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Te sigue" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "posts": "publicacions", + "following": "seguindo", + "followers": "seguidores" }, "fields": { - "add_row": "Add Row", + "add_row": "Anyadir Ringlera", "placeholder": { - "label": "Label", - "content": "Content" + "label": "Nombre pa lo campo", + "content": "Conteniu" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Verificau en %s", + "long": "La propiedat d'este vinclo ha estau verificada lo %s" } }, "segmented_control": { - "posts": "Posts", - "replies": "Replies", - "posts_and_replies": "Posts and Replies", - "media": "Media", - "about": "About" + "posts": "Publicacions", + "replies": "Respuestas", + "posts_and_replies": "Publicacions y respuestas", + "media": "Multimedia", + "about": "Sobre" }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Silenciar cuenta", + "message": "Confirmar pa silenciar %s" }, "confirm_unmute_user": { - "title": "Unmute Account", - "message": "Confirm to unmute %s" + "title": "Deixar de Silenciar Cuenta", + "message": "Confirmar pa deixar de silenciar a %s" }, "confirm_block_user": { - "title": "Block Account", - "message": "Confirm to block %s" + "title": "Blocar cuenta", + "message": "Confirmar pa blocar a %s" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Desbloquiar cuenta", + "message": "Confirmar pa desbloquiar a %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Amostrar los reblogs", + "message": "Confimrar pa amostrar los reblogs" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Amagar los reblogs", + "message": "Comfirmar pa amagar los reblogs" } }, "accessibility": { - "show_avatar_image": "Show avatar image", - "edit_avatar_image": "Edit avatar image", - "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "show_avatar_image": "Amostrar imachen d'o avatar", + "edit_avatar_image": "Editar imachen d'o avatar", + "show_banner_image": "Amostrar imachen de banner", + "double_tap_to_open_the_list": "Preta dos vegadas pa ubrir la lista" } }, "follower": { - "title": "follower", - "footer": "Followers from other servers are not displayed." + "title": "seguidor", + "footer": "No s'amuestran los seguidores d'atros servidors." }, "following": { - "title": "following", - "footer": "Follows from other servers are not displayed." + "title": "seguindo", + "footer": "No s'amuestran los seguius d'atros servidors." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Seguidores que conoixes", + "followed_by_names": "Seguiu per %s" }, "favorited_by": { - "title": "Favorited By" + "title": "Feito favorito per" }, "reblogged_by": { - "title": "Reblogged By" + "title": "Reblogueado per" }, "search": { - "title": "Search", + "title": "Buscar", "search_bar": { - "placeholder": "Search hashtags and users", - "cancel": "Cancel" + "placeholder": "Buscar etiquetas y usuarios", + "cancel": "Cancelar" }, "recommend": { - "button_text": "See All", + "button_text": "Veyer Totas", "hash_tag": { - "title": "Trending on Mastodon", - "description": "Hashtags that are getting quite a bit of attention", - "people_talking": "%s people are talking" + "title": "Tendencias en Mastodon", + "description": "Etiquetas que son recibindo pro atención", + "people_talking": "%s personas son charrando d'esto" }, "accounts": { - "title": "Accounts you might like", - "description": "You may like to follow these accounts", - "follow": "Follow" + "title": "Cuentas que talment quieras seguir", + "description": "Puede que faiga goyo seguir estas cuentas", + "follow": "Seguir" } }, "searching": { "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" + "all": "Tot", + "people": "Chent", + "hashtags": "Etiquetas", + "posts": "Publicacions" }, "empty_state": { - "no_results": "No results" + "no_results": "Sin resultaus" }, - "recent_search": "Recent searches", - "clear": "Clear" + "recent_search": "Busquedas recients", + "clear": "Borrar" } }, "discovery": { "tabs": { - "posts": "Posts", - "hashtags": "Hashtags", - "news": "News", - "community": "Community", - "for_you": "For You" + "posts": "Publicacions", + "hashtags": "Etiquetas", + "news": "Noticias", + "community": "Comunidat", + "for_you": "Pa Tu" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Estas son las publicacions que son ganando tracción en a tuya rincón de Mastodon." }, "favorite": { - "title": "Your Favorites" + "title": "Los tuyos Favoritos" }, "notification": { "title": { - "Everything": "Everything", - "Mentions": "Mentions" + "Everything": "Tot", + "Mentions": "Mencions" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", - "reblogged_your_post": "reblogged your post", - "mentioned_you": "mentioned you", - "request_to_follow_you": "request to follow you", - "poll_has_ended": "poll has ended" + "followed_you": "te siguió", + "favorited_your_post": "ha marcau como favorita la tuya publicación", + "reblogged_your_post": "reblogueó la tuya publicación", + "mentioned_you": "te mencionó", + "request_to_follow_you": "solicitó seguir-te", + "poll_has_ended": "enqüesta ha rematau" }, "keyobard": { - "show_everything": "Show Everything", - "show_mentions": "Show Mentions" + "show_everything": "Amostrar Tot", + "show_mentions": "Amostrar Mencions" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Acceptar", + "accepted": "Acceptau", + "reject": "refusar", + "rejected": "Refusau" } }, "thread": { - "back_title": "Post", - "title": "Post from %s" + "back_title": "Publicación", + "title": "Publicación de %s" }, "settings": { - "title": "Settings", + "title": "Configuración", "section": { "appearance": { - "title": "Appearance", - "automatic": "Automatic", - "light": "Always Light", - "dark": "Always Dark" + "title": "Apariencia", + "automatic": "Automatica", + "light": "Siempre Clara", + "dark": "Siempre Fosca" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "Apariencia", + "use_system": "Uso d'o sistema", + "really_dark": "Realment Fosco", + "sorta_dark": "Más u Menos Fosco", + "light": "Claro" }, "notifications": { - "title": "Notifications", - "favorites": "Favorites my post", - "follows": "Follows me", - "boosts": "Reblogs my post", - "mentions": "Mentions me", + "title": "Notificacions", + "favorites": "Marque como favorita la mía publicación", + "follows": "me siga", + "boosts": "Rebloguee la mía publicación", + "mentions": "me mencione", "trigger": { - "anyone": "anyone", - "follower": "a follower", - "follow": "anyone I follow", - "noone": "no one", - "title": "Notify me when" + "anyone": "qualsequiera", + "follower": "un seguidor", + "follow": "qualsequiera que yo siga", + "noone": "dengún", + "title": "Recibir notificación quan" } }, "preference": { - "title": "Preferences", - "true_black_dark_mode": "True black dark mode", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", - "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "title": "Preferencias", + "true_black_dark_mode": "Modo fosco negro real", + "disable_avatar_animation": "Deshabilitar avatares animaus", + "disable_emoji_animation": "Deshabilitar emojis animaus", + "using_default_browser": "Usar navegador predeterminau pa ubrir los vinclos", + "open_links_in_mastodon": "Ubrir links en Mastodon" }, "boring_zone": { - "title": "The Boring Zone", - "account_settings": "Account Settings", - "terms": "Terms of Service", - "privacy": "Privacy Policy" + "title": "La Zona Aburrida", + "account_settings": "Configuración de Cuenta", + "terms": "Termins de Servicio", + "privacy": "Politica de Privacidat" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", - "signout": "Sign Out" + "title": "La Zona Picante", + "clear": "Borrar Caché de Multimedia", + "signout": "Zarrar Sesión" } }, "footer": { - "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + "mastodon_description": "Mastodon ye software de codigo ubierto. Puetz informar d'errors en GitHub en %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Zarrar Finestra de Configuración" } }, "report": { - "title_report": "Report", - "title": "Report %s", - "step1": "Step 1 of 2", - "step2": "Step 2 of 2", - "content1": "Are there any other posts you’d like to add to the report?", - "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", - "send": "Send Report", - "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED", + "title_report": "Reportar", + "title": "Reportar %s", + "step1": "Paso 1 de 2", + "step2": "Paso 2 de 2", + "content1": "I hai belatra publicación que te fería goyo d'anyadir a lo reporte?", + "content2": "I hai bella cosa que los moderadors habrían de saber sobre este reporte?", + "report_sent_title": "Gracias per denunciar, estudiaremos esto.", + "send": "Ninviar Denuncia", + "skip_to_send": "Ninviar sin comentarios", + "text_placeholder": "Escribe u apega comentarios adicionals", + "reported": "DENUNCIAU", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "step_1_of_4": "Paso 1 de 4", + "whats_wrong_with_this_post": "Qué i hai de malo con esta publicación?", + "whats_wrong_with_this_account": "Qué i hai de malo con esta cuenta?", + "whats_wrong_with_this_username": "Qué i hai de malo con %s?", + "select_the_best_match": "Tría la millor opción", + "i_dont_like_it": "No me fa goyo", + "it_is_not_something_you_want_to_see": "No ye bella cosa que quieras veyer", + "its_spam": "Ye spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Vinclos maliciosos, compromisos falsos u respuestas repetitivas", + "it_violates_server_rules": "Viola las reglas d'o servidor", + "you_are_aware_that_it_breaks_specific_rules": "Yes conscient de que infrinche las normas especificas", + "its_something_else": "Ye bella cosa mas", + "the_issue_does_not_fit_into_other_categories": "Lo problema no encaixa en atras categorías" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", - "i_just_don’t_like_it": "I just don’t like it" + "step_2_of_4": "Paso 2 de 4", + "which_rules_are_being_violated": "Qué normas se son violando?", + "select_all_that_apply": "Tría totz los que correspondan", + "i_just_don’t_like_it": "Nomás no me fa goyo" }, "step_three": { - "step_3_of_4": "Step 3 of 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "step_3_of_4": "Paso 3 de 4", + "are_there_any_posts_that_back_up_this_report": "I hai bella publicación que refirme este informe?", + "select_all_that_apply": "Tría totz los que correspondan" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "Paso 4 de 4", + "is_there_anything_else_we_should_know": "I hai bella cosa mas que habríanos de saber?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", - "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "dont_want_to_see_this": "No quiers veyer esto?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quan veigas bella cosa que no te fa goyo en Mastodon, puetz sacar a la persona d'a tuya experiencia.", + "unfollow": "Deixar de seguir", + "unfollowed": "Ha deixau de seguir-te", + "unfollow_user": "Deixar de seguir a %s", + "mute_user": "Silenciar a %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No veyerás las suyas publicacions u reblogueos en a tuya linia temporal. No sabrán que han estau silenciaus.", + "block_user": "Blocar a %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ya no podrán estar capaces de seguir-te u veyer las tuyas publicacions, pero pueden veyer si han estau blocaus.", + "while_we_review_this_you_can_take_action_against_user": "Mientres revisamos esto, puetz prener medidas contra %s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Zarrar Previsualización", + "show_next": "Amostrar Siguient", + "show_previous": "Amostrar Anterior" } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", - "dismiss_account_switcher": "Dismiss Account Switcher", - "add_account": "Add Account" + "tab_bar_hint": "Perfil triau actualment: %s. Fe un doble toque y mantiene pretau pa amostrar lo selector de cuentas", + "dismiss_account_switcher": "Descartar lo selector de cuentas", + "add_account": "Anyadir cuenta" }, "wizard": { - "new_in_mastodon": "New in Mastodon", - "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", - "accessibility_hint": "Double tap to dismiss this wizard" + "new_in_mastodon": "Nuevo en Mastodon", + "multiple_account_switch_intro_description": "Cambie entre quantas cuentas mantenendo presionado lo botón de perfil.", + "accessibility_hint": "Fe doble toque pa descartar este asistent" }, "bookmark": { - "title": "Bookmarks" + "title": "Marcapachinas" } } } From cb6bc41ae5b34a504fcbd2e1a796f054a1c6658f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:27 +0100 Subject: [PATCH 163/733] New translations ios-infoPlist.json (Aragonese) --- .../StringsConvertor/input/an.lproj/ios-infoPlist.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json index c6db73de0..a493d53d9 100644 --- a/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/an.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" + "NSCameraUsageDescription": "S'usa pa quitar fotos pa las publicacions", + "NSPhotoLibraryAddUsageDescription": "S'usa pa alzar fotos en a Galería de Fotos", + "NewPostShortcutItemTitle": "Nueva Publicación", + "SearchShortcutItemTitle": "Buscar" } From 205c36e51c8e599a13ffc0c111d122fc832c3db6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:28 +0100 Subject: [PATCH 164/733] New translations Localizable.stringsdict (Aragonese) --- .../input/an.lproj/Localizable.stringsdict | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict index 788eb95fc..d7187e039 100644 --- a/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/an.lproj/Localizable.stringsdict @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + 1 notificación no leyida other - %ld unread notifications + %ld notificacions no leyidas a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Limite de dentrada superau en %#@character_count@ caracters character_count NSStringFormatSpecTypeKey @@ -29,15 +29,15 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 caracter other - %ld characters + %ld caracters a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Limite de dentrada restante: %#@character_count@ caracters character_count NSStringFormatSpecTypeKey @@ -45,15 +45,15 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 caracter other - %ld characters + %ld caracters a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + queda %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 caracter other - %ld characters + %ld caracters plural.count.followed_by_and_mutual @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + Seguiu per %1$@ y unatro mutuo other - Followed by %1$@, and %ld mutuals + Seguiu per %1$@ y %ld mutuos plural.count.metric_formatted.post @@ -104,9 +104,9 @@ NSStringFormatValueTypeKey ld one - post + publicación other - posts + publicacions plural.count.media @@ -136,9 +136,9 @@ NSStringFormatValueTypeKey ld one - 1 post + 1 publicación other - %ld posts + %ld publicacions plural.count.favorite @@ -152,9 +152,9 @@ NSStringFormatValueTypeKey ld one - 1 favorite + 1 favorito other - %ld favorites + %ld favoritos plural.count.reblog @@ -168,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 reblog + 1 reblogueo other - %ld reblogs + %ld reblogueos plural.count.reply @@ -184,9 +184,9 @@ NSStringFormatValueTypeKey ld one - 1 reply + 1 respuesta other - %ld replies + %ld respuestas plural.count.vote @@ -200,9 +200,9 @@ NSStringFormatValueTypeKey ld one - 1 vote + 1 voto other - %ld votes + %ld votos plural.count.voter @@ -216,9 +216,9 @@ NSStringFormatValueTypeKey ld one - 1 voter + 1 votante other - %ld voters + %ld votantes plural.people_talking @@ -232,9 +232,9 @@ NSStringFormatValueTypeKey ld one - 1 people talking + 1 persona charrando other - %ld people talking + %ld personas son charrando d'esto plural.count.following @@ -248,9 +248,9 @@ NSStringFormatValueTypeKey ld one - 1 following + 1 seguindo other - %ld following + %ld seguindo plural.count.follower @@ -264,9 +264,9 @@ NSStringFormatValueTypeKey ld one - 1 follower + 1 seguidor other - %ld followers + %ld seguidores date.year.left @@ -280,9 +280,9 @@ NSStringFormatValueTypeKey ld one - 1 year left + 1 anyo restante other - %ld years left + %ld anyos restantes date.month.left @@ -296,9 +296,9 @@ NSStringFormatValueTypeKey ld one - 1 months left + 1 mes restante other - %ld months left + %ld meses restantes date.day.left @@ -312,9 +312,9 @@ NSStringFormatValueTypeKey ld one - 1 day left + 1 día restante other - %ld days left + %ld días restantes date.hour.left @@ -328,9 +328,9 @@ NSStringFormatValueTypeKey ld one - 1 hour left + 1 hora restante other - %ld hours left + %ld horas restantes date.minute.left @@ -344,9 +344,9 @@ NSStringFormatValueTypeKey ld one - 1 minute left + 1 minuto restant other - %ld minutes left + %ld minutos restants date.second.left @@ -360,9 +360,9 @@ NSStringFormatValueTypeKey ld one - 1 second left + 1 segundo restante other - %ld seconds left + %ld segundos restantes date.year.ago.abbr @@ -376,9 +376,9 @@ NSStringFormatValueTypeKey ld one - 1y ago + Fa 1 anyo other - %ldy ago + Fa %ld anyos date.month.ago.abbr @@ -392,9 +392,9 @@ NSStringFormatValueTypeKey ld one - 1M ago + Fa 1 mes other - %ldM ago + Fa %ld meses date.day.ago.abbr @@ -408,9 +408,9 @@ NSStringFormatValueTypeKey ld one - 1d ago + Fa 1 día other - %ldd ago + Fa %ld días date.hour.ago.abbr @@ -424,9 +424,9 @@ NSStringFormatValueTypeKey ld one - 1h ago + Fa 1 h other - %ldh ago + Fa %ld h date.minute.ago.abbr @@ -440,9 +440,9 @@ NSStringFormatValueTypeKey ld one - 1m ago + Fa 1 min other - %ldm ago + Fa %ld min date.second.ago.abbr @@ -456,9 +456,9 @@ NSStringFormatValueTypeKey ld one - 1s ago + Fa 1 s other - %lds ago + Fa %ld s From b2075770d613771cb61998059272d51b90bf1a5f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:29 +0100 Subject: [PATCH 165/733] New translations Intents.strings (Aragonese) --- .../Intents/input/an.lproj/Intents.strings | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings index 6877490ba..597347680 100644 --- a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.strings @@ -1,51 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Publicar en Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Conteniu de Texto"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Publicar en Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Qué conteniu publicar?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Publicación fallida"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Motivo d'o Fallo"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Ninviar Publicación con conteniu de texto"; -"RxSqsb" = "Post"; +"RxSqsb" = "Publicación"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Publicar ${content} en Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Publicación"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Visibilidat"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Visibilidat d'o Post"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "I hai ${count} opcions que coinciden con «Publico»."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "I hai ${count} opcions que coinciden con «Solo seguidores»."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Publico"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Nomás Seguidores"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Publicar en Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Publico"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Solo Seguidores"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Publicación fallida. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Publicación ninviada con exito."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Nomás per confirmar, querebas «Publico»?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Nomás per confirmar, querebas «Nomás seguidores»?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Publicación ninviada con exito. "; From 337537dc1f3b80953cf90724bc85afbcc1c674dc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 01:02:30 +0100 Subject: [PATCH 166/733] New translations Intents.stringsdict (Aragonese) --- .../Intents/input/an.lproj/Intents.stringsdict | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict index 18422c772..9e972ae51 100644 --- a/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/an.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + I hai %#@count_option@ coincidencias con «${content}». count_option NSStringFormatSpecTypeKey @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey %ld one - 1 option + 1 opción other - %ld options + %ld opcions There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + I hai %#@count_option@ coincidencias con «${visibility}». count_option NSStringFormatSpecTypeKey @@ -29,9 +29,9 @@ NSStringFormatValueTypeKey %ld one - 1 option + 1 opción other - %ld options + %ld opcions From 1893d2dd8225bfff50442c197a437603e6a314b2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 02:05:46 +0100 Subject: [PATCH 167/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index b12d26bad..8e09a81cb 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -220,7 +220,7 @@ }, "login": { "title": "مَرحَبًا بِكَ مُجَدَّدًا", - "subtitle": "Log you in on the server you created your account on.", + "subtitle": "سَجِّل دُخولَكَ إلى الخادِم الَّذي أنشأتَ حِسابَكَ فيه.", "server_search_field": { "placeholder": "أدخِل عُنوانَ URL أو اِبحَث عَنِ الخادِمِ الخاصّ بِك" } From 2d37c021e3e147969392352cf844fe4a7b72035a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 02:05:47 +0100 Subject: [PATCH 168/733] New translations Localizable.stringsdict (Arabic) --- .../StringsConvertor/input/ar.lproj/Localizable.stringsdict | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict index 91368a4fb..35727c0d6 100644 --- a/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict @@ -77,7 +77,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + يتبقى %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -91,9 +91,9 @@ two حَرفانِ اِثنان few - %ld characters + %ld أحرُف many - %ld characters + %ld حَرفًا other %ld حَرف From bd0f1c9738c6a1f83d61f6b81774932f8cf7f7da Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 04:45:30 +0100 Subject: [PATCH 169/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index f836f0349..1ba63107c 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "主页", "search": "搜索", - "notifications": "Notifications", + "notifications": "通知", "profile": "个人资料" }, "keyboard": { From d343730947e217f5fa63c421e5bd0c132c38c117 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 05:46:08 +0100 Subject: [PATCH 170/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 14bc718f1..3d3f74971 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Inicio", "search": "Busca", - "notifications": "Notifications", + "notifications": "Notificacións", "profile": "Perfil" }, "keyboard": { From f784df912d1bd1eb859bce47ace5ced2dbf3a7fa Mon Sep 17 00:00:00 2001 From: CMK Date: Tue, 22 Nov 2022 15:58:31 +0800 Subject: [PATCH 171/733] fix: no downscaling for raw image from camera issue --- .../Scene/Compose/ComposeViewController.swift | 1 + .../MastodonUI/Extension/UIImage.swift | 11 ++++ .../AttachmentViewModel+Compress.swift | 59 ++++++++++++++++++- .../Attachment/AttachmentViewModel+Load.swift | 2 +- .../Attachment/AttachmentViewModel.swift | 25 ++++---- .../ComposeContentViewController.swift | 3 + .../ComposeContentViewModel.swift | 14 ++++- .../Scene/ShareViewController.swift | 2 + 8 files changed, 101 insertions(+), 16 deletions(-) diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift index ca33487ab..fbdbc7d12 100644 --- a/Mastodon/Scene/Compose/ComposeViewController.swift +++ b/Mastodon/Scene/Compose/ComposeViewController.swift @@ -209,6 +209,7 @@ extension ComposeViewController { api: viewModel.context.apiService, authContext: viewModel.authContext, input: .image(image), + sizeLimit: composeContentViewModel.sizeLimit, delegate: composeContentViewModel ) } diff --git a/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift b/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift index 141b723bc..5a83e1d61 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift @@ -16,3 +16,14 @@ extension UIImage { } } + +extension UIImage { + public func normalized() -> UIImage? { + if imageOrientation == .up { return self } + UIGraphicsBeginImageContext(size) + draw(in: CGRect(origin: CGPoint.zero, size: size)) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image + } + } diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift index e5d6702ad..6df22d324 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift @@ -8,11 +8,12 @@ import os.log import UIKit import AVKit -import SessionExporter import MastodonCore +import SessionExporter +import Kingfisher extension AttachmentViewModel { - func comporessVideo(url: URL) async throws -> URL { + func compressVideo(url: URL) async throws -> URL { let urlAsset = AVURLAsset(url: url) let exporter = NextLevelSessionExporter(withAsset: urlAsset) exporter.outputFileType = .mp4 @@ -92,3 +93,57 @@ extension AttachmentViewModel { } } // end func } + +extension AttachmentViewModel { + @AttachmentViewModelActor + func compressImage(data: Data, sizeLimit: SizeLimit) throws -> Output { + let maxPayloadSizeInBytes = sizeLimit.image ?? 10 * 1024 * 1024 + + guard let image = KFCrossPlatformImage(data: data)?.kf.normalized, + var imageData = image.kf.pngRepresentation() + else { + throw AttachmentError.invalidAttachmentType + } + + repeat { + guard let image = KFCrossPlatformImage(data: imageData) else { + throw AttachmentError.invalidAttachmentType + } + + if imageData.kf.imageFormat == .PNG { + // A. png image + if imageData.count > maxPayloadSizeInBytes { + guard let compressedJpegData = image.jpegData(compressionQuality: 0.8) else { + throw AttachmentError.invalidAttachmentType + } + os_log("%{public}s[%{public}ld], %{public}s: compress png %.2fMiB -> jpeg %.2fMiB", ((#file as NSString).lastPathComponent), #line, #function, Double(imageData.count) / 1024 / 1024, Double(compressedJpegData.count) / 1024 / 1024) + imageData = compressedJpegData + } else { + os_log("%{public}s[%{public}ld], %{public}s: png %.2fMiB", ((#file as NSString).lastPathComponent), #line, #function, Double(imageData.count) / 1024 / 1024) + break + } + } else { + // B. other image + if imageData.count > maxPayloadSizeInBytes { + let targetSize = CGSize(width: image.size.width * 0.8, height: image.size.height * 0.8) + let scaledImage = image.kf.resize(to: targetSize) + guard let compressedJpegData = scaledImage.jpegData(compressionQuality: 0.8) else { + throw AttachmentError.invalidAttachmentType + } + os_log("%{public}s[%{public}ld], %{public}s: compress jpeg %.2fMiB -> jpeg %.2fMiB", ((#file as NSString).lastPathComponent), #line, #function, Double(imageData.count) / 1024 / 1024, Double(compressedJpegData.count) / 1024 / 1024) + imageData = compressedJpegData + } else { + os_log("%{public}s[%{public}ld], %{public}s: jpeg %.2fMiB", ((#file as NSString).lastPathComponent), #line, #function, Double(imageData.count) / 1024 / 1024) + break + } + } + } while (imageData.count > maxPayloadSizeInBytes) + + + return .image(imageData, imageKind: imageData.kf.imageFormat == .PNG ? .png : .jpg) + } +} + +@globalActor actor AttachmentViewModelActor { + static var shared = AttachmentViewModelActor() +} diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Load.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Load.swift index a259485f1..7cfd51eb5 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Load.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Load.swift @@ -16,7 +16,7 @@ extension AttachmentViewModel { func load(input: Input) async throws -> Output { switch input { case .image(let image): - guard let data = image.pngData() else { + guard let data = image.normalized()?.pngData() else { throw AttachmentError.invalidAttachmentType } return .image(data, imageKind: .png) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift index 18da157c5..e420d9ad1 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift @@ -48,8 +48,8 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable public let api: APIService public let authContext: AuthContext public let input: Input + public let sizeLimit: SizeLimit @Published var caption = "" - // @Published var sizeLimit = SizeLimit() // output @Published public private(set) var output: Output? @@ -77,11 +77,13 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable api: APIService, authContext: AuthContext, input: Input, + sizeLimit: SizeLimit, delegate: AttachmentViewModelDelegate ) { self.api = api self.authContext = authContext self.input = input + self.sizeLimit = sizeLimit self.delegate = delegate super.init() // end init @@ -137,14 +139,17 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable var output = try await load(input: input) switch output { + case .image(let data, _): + self.output = output + self.update(uploadState: .compressing) + let compressedOutput = try await compressImage(data: data, sizeLimit: sizeLimit) + output = compressedOutput case .video(let fileURL, let mimeType): self.output = output self.update(uploadState: .compressing) - let compressedFileURL = try await comporessVideo(url: fileURL) + let compressedFileURL = try await compressVideo(url: fileURL) output = .video(compressedFileURL, mimeType: mimeType) try? FileManager.default.removeItem(at: fileURL) // remove old file - default: - break } self.outputSizeInByte = output.asAttachment.sizeInByte.flatMap { Int64($0) } ?? 0 @@ -262,19 +267,15 @@ extension AttachmentViewModel { } } - // not in using public struct SizeLimit { - public let image: Int - public let gif: Int - public let video: Int + public let image: Int? + public let video: Int? public init( - image: Int = 10 * 1024 * 1024, // 10 MiB - gif: Int = 40 * 1024 * 1024, // 40 MiB - video: Int = 40 * 1024 * 1024 // 40 MiB + image: Int?, + video: Int? ) { self.image = image - self.gif = gif self.video = video } } diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift index 811da063a..319804fb1 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift @@ -435,6 +435,7 @@ extension ComposeContentViewController: PHPickerViewControllerDelegate { api: viewModel.context.apiService, authContext: viewModel.authContext, input: .pickerResult(result), + sizeLimit: viewModel.sizeLimit, delegate: viewModel ) } @@ -453,6 +454,7 @@ extension ComposeContentViewController: UIImagePickerControllerDelegate & UINavi api: viewModel.context.apiService, authContext: viewModel.authContext, input: .image(image), + sizeLimit: viewModel.sizeLimit, delegate: viewModel ) viewModel.attachmentViewModels += [attachmentViewModel] @@ -473,6 +475,7 @@ extension ComposeContentViewController: UIDocumentPickerDelegate { api: viewModel.context.apiService, authContext: viewModel.authContext, input: .url(url), + sizeLimit: viewModel.sizeLimit, delegate: viewModel ) viewModel.attachmentViewModels += [attachmentViewModel] diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index 3321aeab7..a1ddb6101 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -88,7 +88,7 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { // attachment @Published public var attachmentViewModels: [AttachmentViewModel] = [] @Published public var maxMediaAttachmentLimit = 4 - // @Published public internal(set) var isMediaValid = true + @Published public internal(set) var maxImageMediaSizeLimitInByte = 10 * 1024 * 1024 // 10 MiB // poll @Published public var isPollActive = false @@ -126,6 +126,14 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { @Published var isPollButtonEnabled = false @Published public private(set) var shouldDismiss = true + + // size limit + public var sizeLimit: AttachmentViewModel.SizeLimit { + AttachmentViewModel.SizeLimit( + image: maxImageMediaSizeLimitInByte, + video: nil + ) + } public init( context: AppContext, @@ -252,6 +260,10 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { if let maxOptions = configuration.polls?.maxOptions { maxPollOptionLimit = maxOptions } + // set photo attachment limit + if let imageSizeLimit = configuration.mediaAttachments?.imageSizeLimit { + maxImageMediaSizeLimitInByte = imageSizeLimit + } // TODO: more limit } diff --git a/ShareActionExtension/Scene/ShareViewController.swift b/ShareActionExtension/Scene/ShareViewController.swift index 372ce5876..4a093becd 100644 --- a/ShareActionExtension/Scene/ShareViewController.swift +++ b/ShareActionExtension/Scene/ShareViewController.swift @@ -276,6 +276,7 @@ extension ShareViewController { api: context.apiService, authContext: authContext, input: .itemProvider(movieProvider), + sizeLimit: .init(image: nil, video: nil), delegate: composeContentViewModel ) composeContentViewModel.attachmentViewModels.append(attachmentViewModel) @@ -285,6 +286,7 @@ extension ShareViewController { api: context.apiService, authContext: authContext, input: .itemProvider(provider), + sizeLimit: .init(image: nil, video: nil), delegate: composeContentViewModel ) } From f44b0d4e1472376d41949dd43bd5f1d30e52d221 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:12 +0100 Subject: [PATCH 172/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 9884430ce..4a9c690f0 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -216,7 +216,7 @@ "welcome": { "slogan": "Los retz socials\nde nuevo en as tuyas mans.", "get_started": "Empecipiar", - "log_in": "Encetar sesión" + "log_in": "Iniciar sesión" }, "login": { "title": "Bienveniu de nuevas", From 2a0864a13f38d335d6dba5ea14bd74ee88405430 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:13 +0100 Subject: [PATCH 173/733] New translations app.json (Hebrew) --- .../StringsConvertor/input/he.lproj/app.json | 727 ++++++++++++++++++ 1 file changed, 727 insertions(+) create mode 100644 Localization/StringsConvertor/input/he.lproj/app.json diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json new file mode 100644 index 000000000..c757b4979 --- /dev/null +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -0,0 +1,727 @@ +{ + "common": { + "alerts": { + "common": { + "please_try_again": "Please try again.", + "please_try_again_later": "Please try again later." + }, + "sign_up_failure": { + "title": "Sign Up Failure" + }, + "server_error": { + "title": "Server Error" + }, + "vote_failure": { + "title": "Vote Failure", + "poll_ended": "The poll has ended" + }, + "discard_post_content": { + "title": "Discard Draft", + "message": "Confirm to discard composed post content." + }, + "publish_post_failure": { + "title": "Publish Failure", + "message": "Failed to publish the post.\nPlease check your internet connection.", + "attachments_message": { + "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", + "more_than_one_video": "Cannot attach more than one video." + } + }, + "edit_profile_failure": { + "title": "Edit Profile Error", + "message": "Cannot edit profile. Please try again." + }, + "sign_out": { + "title": "Sign Out", + "message": "Are you sure you want to sign out?", + "confirm": "Sign Out" + }, + "block_domain": { + "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", + "block_entire_domain": "Block Domain" + }, + "save_photo_failure": { + "title": "Save Photo Failure", + "message": "Please enable the photo library access permission to save the photo." + }, + "delete_post": { + "title": "Delete Post", + "message": "Are you sure you want to delete this post?" + }, + "clean_cache": { + "title": "Clean Cache", + "message": "Successfully cleaned %s cache." + } + }, + "controls": { + "actions": { + "back": "Back", + "next": "Next", + "previous": "Previous", + "open": "Open", + "add": "Add", + "remove": "Remove", + "edit": "Edit", + "save": "Save", + "ok": "OK", + "done": "Done", + "confirm": "Confirm", + "continue": "Continue", + "compose": "Compose", + "cancel": "Cancel", + "discard": "Discard", + "try_again": "Try Again", + "take_photo": "Take Photo", + "save_photo": "Save Photo", + "copy_photo": "Copy Photo", + "sign_in": "Log in", + "sign_up": "Create account", + "see_more": "See More", + "preview": "Preview", + "share": "Share", + "share_user": "Share %s", + "share_post": "Share Post", + "open_in_safari": "Open in Safari", + "open_in_browser": "Open in Browser", + "find_people": "Find people to follow", + "manually_search": "Manually search instead", + "skip": "Skip", + "reply": "Reply", + "report_user": "Report %s", + "block_domain": "Block %s", + "unblock_domain": "Unblock %s", + "settings": "Settings", + "delete": "Delete" + }, + "tabs": { + "home": "Home", + "search": "Search", + "notifications": "Notifications", + "profile": "Profile" + }, + "keyboard": { + "common": { + "switch_to_tab": "Switch to %s", + "compose_new_post": "Compose New Post", + "show_favorites": "Show Favorites", + "open_settings": "Open Settings" + }, + "timeline": { + "previous_status": "Previous Post", + "next_status": "Next Post", + "open_status": "Open Post", + "open_author_profile": "Open Author's Profile", + "open_reblogger_profile": "Open Reblogger's Profile", + "reply_status": "Reply to Post", + "toggle_reblog": "Toggle Reblog on Post", + "toggle_favorite": "Toggle Favorite on Post", + "toggle_content_warning": "Toggle Content Warning", + "preview_image": "Preview Image" + }, + "segmented_control": { + "previous_section": "Previous Section", + "next_section": "Next Section" + } + }, + "status": { + "user_reblogged": "%s reblogged", + "user_replied_to": "Replied to %s", + "show_post": "Show Post", + "show_user_profile": "Show user profile", + "content_warning": "Content Warning", + "sensitive_content": "Sensitive Content", + "media_content_warning": "Tap anywhere to reveal", + "tap_to_reveal": "Tap to reveal", + "poll": { + "vote": "Vote", + "closed": "Closed" + }, + "meta_entity": { + "url": "Link: %s", + "hashtag": "Hashtag: %s", + "mention": "Show Profile: %s", + "email": "Email address: %s" + }, + "actions": { + "reply": "Reply", + "reblog": "Reblog", + "unreblog": "Undo reblog", + "favorite": "Favorite", + "unfavorite": "Unfavorite", + "menu": "Menu", + "hide": "Hide", + "show_image": "Show image", + "show_gif": "Show GIF", + "show_video_player": "Show video player", + "tap_then_hold_to_show_menu": "Tap then hold to show menu" + }, + "tag": { + "url": "URL", + "mention": "Mention", + "link": "Link", + "hashtag": "Hashtag", + "email": "Email", + "emoji": "Emoji" + }, + "visibility": { + "unlisted": "Everyone can see this post but not display in the public timeline.", + "private": "Only their followers can see this post.", + "private_from_me": "Only my followers can see this post.", + "direct": "Only mentioned user can see this post." + } + }, + "friendship": { + "follow": "Follow", + "following": "Following", + "request": "Request", + "pending": "Pending", + "block": "Block", + "block_user": "Block %s", + "block_domain": "Block %s", + "unblock": "Unblock", + "unblock_user": "Unblock %s", + "blocked": "Blocked", + "mute": "Mute", + "mute_user": "Mute %s", + "unmute": "Unmute", + "unmute_user": "Unmute %s", + "muted": "Muted", + "edit_info": "Edit Info", + "show_reblogs": "Show Reblogs", + "hide_reblogs": "Hide Reblogs" + }, + "timeline": { + "filtered": "Filtered", + "timestamp": { + "now": "Now" + }, + "loader": { + "load_missing_posts": "Load missing posts", + "loading_missing_posts": "Loading missing posts...", + "show_more_replies": "Show more replies" + }, + "header": { + "no_status_found": "No Post Found", + "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", + "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", + "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", + "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "suspended_warning": "This user has been suspended.", + "user_suspended_warning": "%s’s account has been suspended." + } + } + } + }, + "scene": { + "welcome": { + "slogan": "Social networking\nback in your hands.", + "get_started": "Get Started", + "log_in": "Log In" + }, + "login": { + "title": "Welcome back", + "subtitle": "Log you in on the server you created your account on.", + "server_search_field": { + "placeholder": "Enter URL or search for your server" + } + }, + "server_picker": { + "title": "Mastodon is made of users in different servers.", + "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "button": { + "category": { + "all": "All", + "all_accessiblity_description": "Category: All", + "academia": "academia", + "activism": "activism", + "food": "food", + "furry": "furry", + "games": "games", + "general": "general", + "journalism": "journalism", + "lgbt": "lgbt", + "regional": "regional", + "art": "art", + "music": "music", + "tech": "tech" + }, + "see_less": "See Less", + "see_more": "See More" + }, + "label": { + "language": "LANGUAGE", + "users": "USERS", + "category": "CATEGORY" + }, + "input": { + "search_servers_or_enter_url": "Search communities or enter URL" + }, + "empty_state": { + "finding_servers": "Finding available servers...", + "bad_network": "Something went wrong while loading the data. Check your internet connection.", + "no_results": "No results" + } + }, + "register": { + "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "input": { + "avatar": { + "delete": "Delete" + }, + "username": { + "placeholder": "username", + "duplicate_prompt": "This username is taken." + }, + "display_name": { + "placeholder": "display name" + }, + "email": { + "placeholder": "email" + }, + "password": { + "placeholder": "password", + "require": "Your password needs at least:", + "character_limit": "8 characters", + "accessibility": { + "checked": "checked", + "unchecked": "unchecked" + }, + "hint": "Your password needs at least eight characters" + }, + "invite": { + "registration_user_invite_request": "Why do you want to join?" + } + }, + "error": { + "item": { + "username": "Username", + "email": "Email", + "password": "Password", + "agreement": "Agreement", + "locale": "Locale", + "reason": "Reason" + }, + "reason": { + "blocked": "%s contains a disallowed email provider", + "unreachable": "%s does not seem to exist", + "taken": "%s is already in use", + "reserved": "%s is a reserved keyword", + "accepted": "%s must be accepted", + "blank": "%s is required", + "invalid": "%s is invalid", + "too_long": "%s is too long", + "too_short": "%s is too short", + "inclusion": "%s is not a supported value" + }, + "special": { + "username_invalid": "Username must only contain alphanumeric characters and underscores", + "username_too_long": "Username is too long (can’t be longer than 30 characters)", + "email_invalid": "This is not a valid email address", + "password_too_short": "Password is too short (must be at least 8 characters)" + } + } + }, + "server_rules": { + "title": "Some ground rules.", + "subtitle": "These are set and enforced by the %s moderators.", + "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "terms_of_service": "terms of service", + "privacy_policy": "privacy policy", + "button": { + "confirm": "I Agree" + } + }, + "confirm_email": { + "title": "One last thing.", + "subtitle": "Tap the link we emailed to you to verify your account.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "button": { + "open_email_app": "Open Email App", + "resend": "Resend" + }, + "dont_receive_email": { + "title": "Check your email", + "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "resend_email": "Resend Email" + }, + "open_email_app": { + "title": "Check your inbox.", + "description": "We just sent you an email. Check your junk folder if you haven’t.", + "mail": "Mail", + "open_email_client": "Open Email Client" + } + }, + "home_timeline": { + "title": "Home", + "navigation_bar_state": { + "offline": "Offline", + "new_posts": "See new posts", + "published": "Published!", + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } + } + }, + "suggestion_account": { + "title": "Find People to Follow", + "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + }, + "compose": { + "title": { + "new_post": "New Post", + "new_reply": "New Reply" + }, + "media_selection": { + "camera": "Take Photo", + "photo_library": "Photo Library", + "browse": "Browse" + }, + "content_input_placeholder": "Type or paste what’s on your mind", + "compose_action": "Publish", + "replying_to_user": "replying to %s", + "attachment": { + "photo": "photo", + "video": "video", + "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "description_photo": "Describe the photo for the visually-impaired...", + "description_video": "Describe the video for the visually-impaired...", + "load_failed": "Load Failed", + "upload_failed": "Upload Failed", + "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", + "attachment_too_large": "Attachment too large", + "compressing_state": "Compressing...", + "server_processing_state": "Server Processing..." + }, + "poll": { + "duration_time": "Duration: %s", + "thirty_minutes": "30 minutes", + "one_hour": "1 Hour", + "six_hours": "6 Hours", + "one_day": "1 Day", + "three_days": "3 Days", + "seven_days": "7 Days", + "option_number": "Option %ld", + "the_poll_is_invalid": "The poll is invalid", + "the_poll_has_empty_option": "The poll has empty option" + }, + "content_warning": { + "placeholder": "Write an accurate warning here..." + }, + "visibility": { + "public": "Public", + "unlisted": "Unlisted", + "private": "Followers only", + "direct": "Only people I mention" + }, + "auto_complete": { + "space_to_add": "Space to add" + }, + "accessibility": { + "append_attachment": "Add Attachment", + "append_poll": "Add Poll", + "remove_poll": "Remove Poll", + "custom_emoji_picker": "Custom Emoji Picker", + "enable_content_warning": "Enable Content Warning", + "disable_content_warning": "Disable Content Warning", + "post_visibility_menu": "Post Visibility Menu", + "post_options": "Post Options", + "posting_as": "Posting as %s" + }, + "keyboard": { + "discard_post": "Discard Post", + "publish_post": "Publish Post", + "toggle_poll": "Toggle Poll", + "toggle_content_warning": "Toggle Content Warning", + "append_attachment_entry": "Add Attachment - %s", + "select_visibility_entry": "Select Visibility - %s" + } + }, + "profile": { + "header": { + "follows_you": "Follows You" + }, + "dashboard": { + "posts": "posts", + "following": "following", + "followers": "followers" + }, + "fields": { + "add_row": "Add Row", + "placeholder": { + "label": "Label", + "content": "Content" + }, + "verified": { + "short": "Verified on %s", + "long": "Ownership of this link was checked on %s" + } + }, + "segmented_control": { + "posts": "Posts", + "replies": "Replies", + "posts_and_replies": "Posts and Replies", + "media": "Media", + "about": "About" + }, + "relationship_action_alert": { + "confirm_mute_user": { + "title": "Mute Account", + "message": "Confirm to mute %s" + }, + "confirm_unmute_user": { + "title": "Unmute Account", + "message": "Confirm to unmute %s" + }, + "confirm_block_user": { + "title": "Block Account", + "message": "Confirm to block %s" + }, + "confirm_unblock_user": { + "title": "Unblock Account", + "message": "Confirm to unblock %s" + }, + "confirm_show_reblogs": { + "title": "Show Reblogs", + "message": "Confirm to show reblogs" + }, + "confirm_hide_reblogs": { + "title": "Hide Reblogs", + "message": "Confirm to hide reblogs" + } + }, + "accessibility": { + "show_avatar_image": "Show avatar image", + "edit_avatar_image": "Edit avatar image", + "show_banner_image": "Show banner image", + "double_tap_to_open_the_list": "Double tap to open the list" + } + }, + "follower": { + "title": "follower", + "footer": "Followers from other servers are not displayed." + }, + "following": { + "title": "following", + "footer": "Follows from other servers are not displayed." + }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, + "search": { + "title": "Search", + "search_bar": { + "placeholder": "Search hashtags and users", + "cancel": "Cancel" + }, + "recommend": { + "button_text": "See All", + "hash_tag": { + "title": "Trending on Mastodon", + "description": "Hashtags that are getting quite a bit of attention", + "people_talking": "%s people are talking" + }, + "accounts": { + "title": "Accounts you might like", + "description": "You may like to follow these accounts", + "follow": "Follow" + } + }, + "searching": { + "segment": { + "all": "All", + "people": "People", + "hashtags": "Hashtags", + "posts": "Posts" + }, + "empty_state": { + "no_results": "No results" + }, + "recent_search": "Recent searches", + "clear": "Clear" + } + }, + "discovery": { + "tabs": { + "posts": "Posts", + "hashtags": "Hashtags", + "news": "News", + "community": "Community", + "for_you": "For You" + }, + "intro": "These are the posts gaining traction in your corner of Mastodon." + }, + "favorite": { + "title": "Your Favorites" + }, + "notification": { + "title": { + "Everything": "Everything", + "Mentions": "Mentions" + }, + "notification_description": { + "followed_you": "followed you", + "favorited_your_post": "favorited your post", + "reblogged_your_post": "reblogged your post", + "mentioned_you": "mentioned you", + "request_to_follow_you": "request to follow you", + "poll_has_ended": "poll has ended" + }, + "keyobard": { + "show_everything": "Show Everything", + "show_mentions": "Show Mentions" + }, + "follow_request": { + "accept": "Accept", + "accepted": "Accepted", + "reject": "reject", + "rejected": "Rejected" + } + }, + "thread": { + "back_title": "Post", + "title": "Post from %s" + }, + "settings": { + "title": "Settings", + "section": { + "appearance": { + "title": "Appearance", + "automatic": "Automatic", + "light": "Always Light", + "dark": "Always Dark" + }, + "look_and_feel": { + "title": "Look and Feel", + "use_system": "Use System", + "really_dark": "Really Dark", + "sorta_dark": "Sorta Dark", + "light": "Light" + }, + "notifications": { + "title": "Notifications", + "favorites": "Favorites my post", + "follows": "Follows me", + "boosts": "Reblogs my post", + "mentions": "Mentions me", + "trigger": { + "anyone": "anyone", + "follower": "a follower", + "follow": "anyone I follow", + "noone": "no one", + "title": "Notify me when" + } + }, + "preference": { + "title": "Preferences", + "true_black_dark_mode": "True black dark mode", + "disable_avatar_animation": "Disable animated avatars", + "disable_emoji_animation": "Disable animated emojis", + "using_default_browser": "Use default browser to open links", + "open_links_in_mastodon": "Open links in Mastodon" + }, + "boring_zone": { + "title": "The Boring Zone", + "account_settings": "Account Settings", + "terms": "Terms of Service", + "privacy": "Privacy Policy" + }, + "spicy_zone": { + "title": "The Spicy Zone", + "clear": "Clear Media Cache", + "signout": "Sign Out" + } + }, + "footer": { + "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + }, + "keyboard": { + "close_settings_window": "Close Settings Window" + } + }, + "report": { + "title_report": "Report", + "title": "Report %s", + "step1": "Step 1 of 2", + "step2": "Step 2 of 2", + "content1": "Are there any other posts you’d like to add to the report?", + "content2": "Is there anything the moderators should know about this report?", + "report_sent_title": "Thanks for reporting, we’ll look into this.", + "send": "Send Report", + "skip_to_send": "Send without comment", + "text_placeholder": "Type or paste additional comments", + "reported": "REPORTED", + "step_one": { + "step_1_of_4": "Step 1 of 4", + "whats_wrong_with_this_post": "What's wrong with this post?", + "whats_wrong_with_this_account": "What's wrong with this account?", + "whats_wrong_with_this_username": "What's wrong with %s?", + "select_the_best_match": "Select the best match", + "i_dont_like_it": "I don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "it_violates_server_rules": "It violates server rules", + "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "its_something_else": "It’s something else", + "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + }, + "step_two": { + "step_2_of_4": "Step 2 of 4", + "which_rules_are_being_violated": "Which rules are being violated?", + "select_all_that_apply": "Select all that apply", + "i_just_don’t_like_it": "I just don’t like it" + }, + "step_three": { + "step_3_of_4": "Step 3 of 4", + "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", + "select_all_that_apply": "Select all that apply" + }, + "step_four": { + "step_4_of_4": "Step 4 of 4", + "is_there_anything_else_we_should_know": "Is there anything else we should know?" + }, + "step_final": { + "dont_want_to_see_this": "Don’t want to see this?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "unfollow": "Unfollow", + "unfollowed": "Unfollowed", + "unfollow_user": "Unfollow %s", + "mute_user": "Mute %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "block_user": "Block %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } + }, + "preview": { + "keyboard": { + "close_preview": "Close Preview", + "show_next": "Show Next", + "show_previous": "Show Previous" + } + }, + "account_list": { + "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", + "dismiss_account_switcher": "Dismiss Account Switcher", + "add_account": "Add Account" + }, + "wizard": { + "new_in_mastodon": "New in Mastodon", + "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", + "accessibility_hint": "Double tap to dismiss this wizard" + }, + "bookmark": { + "title": "Bookmarks" + } + } +} From d1d3cb6536b8c0a4bb0844e316e3b946d8949932 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:14 +0100 Subject: [PATCH 174/733] New translations ios-infoPlist.json (Hebrew) --- .../StringsConvertor/input/he.lproj/ios-infoPlist.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Localization/StringsConvertor/input/he.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/he.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/he.lproj/ios-infoPlist.json new file mode 100644 index 000000000..c6db73de0 --- /dev/null +++ b/Localization/StringsConvertor/input/he.lproj/ios-infoPlist.json @@ -0,0 +1,6 @@ +{ + "NSCameraUsageDescription": "Used to take photo for post status", + "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NewPostShortcutItemTitle": "New Post", + "SearchShortcutItemTitle": "Search" +} From 9b78928fa876f7a7c72ff4faf1abfbd1e0e687c2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:15 +0100 Subject: [PATCH 175/733] New translations Localizable.stringsdict (Hebrew) --- .../input/he.lproj/Localizable.stringsdict | 581 ++++++++++++++++++ 1 file changed, 581 insertions(+) create mode 100644 Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict diff --git a/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict new file mode 100644 index 000000000..bd6cea903 --- /dev/null +++ b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict @@ -0,0 +1,581 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 unread notification + two + %ld unread notifications + many + %ld unread notifications + other + %ld unread notifications + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + Input limit exceeds %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + two + %ld characters + many + %ld characters + other + %ld characters + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + Input limit remains %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + two + %ld characters + many + %ld characters + other + %ld characters + + + a11y.plural.count.characters_left + + NSStringLocalizedFormatKey + %#@character_count@ left + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + two + %ld characters + many + %ld characters + other + %ld characters + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + two + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + two + Followed by %1$@, and %ld mutuals + many + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + post + two + posts + many + posts + other + posts + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + two + %ld media + many + %ld media + other + %ld media + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 post + two + %ld posts + many + %ld posts + other + %ld posts + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 favorite + two + %ld favorites + many + %ld favorites + other + %ld favorites + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reblog + two + %ld reblogs + many + %ld reblogs + other + %ld reblogs + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reply + two + %ld replies + many + %ld replies + other + %ld replies + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 vote + two + %ld votes + many + %ld votes + other + %ld votes + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 voter + two + %ld voters + many + %ld voters + other + %ld voters + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 people talking + two + %ld people talking + many + %ld people talking + other + %ld people talking + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 following + two + %ld following + many + %ld following + other + %ld following + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 follower + two + %ld followers + many + %ld followers + other + %ld followers + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 year left + two + %ld years left + many + %ld years left + other + %ld years left + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 months left + two + %ld months left + many + %ld months left + other + %ld months left + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 day left + two + %ld days left + many + %ld days left + other + %ld days left + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 hour left + two + %ld hours left + many + %ld hours left + other + %ld hours left + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 minute left + two + %ld minutes left + many + %ld minutes left + other + %ld minutes left + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 second left + two + %ld seconds left + many + %ld seconds left + other + %ld seconds left + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1y ago + two + %ldy ago + many + %ldy ago + other + %ldy ago + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1M ago + two + %ldM ago + many + %ldM ago + other + %ldM ago + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1d ago + two + %ldd ago + many + %ldd ago + other + %ldd ago + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1h ago + two + %ldh ago + many + %ldh ago + other + %ldh ago + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1m ago + two + %ldm ago + many + %ldm ago + other + %ldm ago + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1s ago + two + %lds ago + many + %lds ago + other + %lds ago + + + + From c7f2811a51a86fe6b4b0a7d0e7459fe18839e92e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:16 +0100 Subject: [PATCH 176/733] New translations Intents.strings (Hebrew) --- .../Intents/input/he.lproj/Intents.strings | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/he.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/he.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/he.lproj/Intents.strings new file mode 100644 index 000000000..6877490ba --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/he.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Post on Mastodon"; + +"751xkl" = "Text Content"; + +"CsR7G2" = "Post on Mastodon"; + +"HZSGTr" = "What content to post?"; + +"HdGikU" = "Posting failed"; + +"KDNTJ4" = "Failure Reason"; + +"RHxKOw" = "Send Post with text content"; + +"RxSqsb" = "Post"; + +"WCIR3D" = "Post ${content} on Mastodon"; + +"ZKJSNu" = "Post"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Visibility"; + +"Zo4jgJ" = "Post Visibility"; + +"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; + +"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; + +"ayoYEb-dYQ5NN" = "${content}, Public"; + +"ayoYEb-ehFLjY" = "${content}, Followers Only"; + +"dUyuGg" = "Post on Mastodon"; + +"dYQ5NN" = "Public"; + +"ehFLjY" = "Followers Only"; + +"gfePDu" = "Posting failed. ${failureReason}"; + +"k7dbKQ" = "Post was sent successfully."; + +"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; + +"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Post was sent successfully. "; From 297637f1f545d13a4d5782124473e644f99b7640 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 09:43:18 +0100 Subject: [PATCH 177/733] New translations Intents.stringsdict (Hebrew) --- .../input/he.lproj/Intents.stringsdict | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Localization/StringsConvertor/Intents/input/he.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/he.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/he.lproj/Intents.stringsdict new file mode 100644 index 000000000..c88207000 --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/he.lproj/Intents.stringsdict @@ -0,0 +1,46 @@ + + + + + There are ${count} options matching ‘${content}’. - 2 + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${content}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 option + two + %ld options + many + %ld options + other + %ld options + + + There are ${count} options matching ‘${visibility}’. + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${visibility}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 option + two + %ld options + many + %ld options + other + %ld options + + + + From a6c1e8569af5be96219b97537050c651b2fd3441 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 10:50:32 +0100 Subject: [PATCH 178/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index d0c8bbb5c..8f83803b3 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Serrûpel", "search": "Bigere", - "notifications": "Notifications", + "notifications": "Agahdarî", "profile": "Profîl" }, "keyboard": { From 43604a485e016d3a09d1d5b7716ef8bffdc0dbab Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 13:23:21 +0100 Subject: [PATCH 179/733] New translations app.json (Japanese) --- .../StringsConvertor/input/ja.lproj/app.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 3ea037335..c04478f78 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -75,7 +75,7 @@ "save_photo": "写真を保存", "copy_photo": "写真をコピー", "sign_in": "ログイン", - "sign_up": "Create account", + "sign_up": "アカウント作成", "see_more": "もっと見る", "preview": "プレビュー", "share": "共有", @@ -96,7 +96,7 @@ "tabs": { "home": "ホーム", "search": "検索", - "notifications": "Notifications", + "notifications": "通知", "profile": "プロフィール" }, "keyboard": { @@ -137,10 +137,10 @@ "closed": "終了" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "リンク: %s", + "hashtag": "ハッシュタグ: %s", + "mention": "プロフィールを表示: %s", + "email": "メールアドレス: %s" }, "actions": { "reply": "返信", @@ -220,14 +220,14 @@ }, "login": { "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "subtitle": "アカウントを作成したサーバーにログインします。", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "URLを入力またはサーバーを検索" } }, "server_picker": { "title": "サーバーを選択", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "お住まいの地域、興味、目的に基づいてサーバーを選択してください。 サーバーに関係なく、Mastodonの誰とでも話せます。", "button": { "category": { "all": "すべて", @@ -254,7 +254,7 @@ "category": "カテゴリー" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "コミュニティを検索またはURLを入力" }, "empty_state": { "finding_servers": "利用可能なサーバーの検索...", From 89b1419f918a060617a63f785d80c31765d04efd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 17:02:16 +0100 Subject: [PATCH 180/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 91289f461..f19615052 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -175,10 +175,10 @@ "following": "Seguint", "request": "Petició", "pending": "Pendent", - "block": "Bloqueja", - "block_user": "Bloqueja %s", - "block_domain": "Bloqueja %s", - "unblock": "Desbloqueja", + "block": "Bloca", + "block_user": "Bloca %s", + "block_domain": "Bloca %s", + "unblock": "Desbloca", "unblock_user": "Desbloqueja %s", "blocked": "Bloquejat", "mute": "Silencia", From d000b72ac5adc31dd2eb794dda156315d9fb9691 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 18:07:52 +0100 Subject: [PATCH 181/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index f19615052..b624b194d 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -179,8 +179,8 @@ "block_user": "Bloca %s", "block_domain": "Bloca %s", "unblock": "Desbloca", - "unblock_user": "Desbloqueja %s", - "blocked": "Bloquejat", + "unblock_user": "Desbloca %s", + "blocked": "Blocat", "mute": "Silencia", "mute_user": "Silencia %s", "unmute": "Deixa de silenciar", @@ -196,16 +196,16 @@ "now": "Ara" }, "loader": { - "load_missing_posts": "Carrega les publicacions faltants", - "loading_missing_posts": "Carregant les publicacions faltants...", + "load_missing_posts": "Carrega les publicacions restants", + "loading_missing_posts": "Carregant les publicacions restants...", "show_more_replies": "Mostra més respostes" }, "header": { "no_status_found": "No s'ha trobat cap publicació", - "blocking_warning": "No pots veure el perfil d'aquest usuari\n fins que el desbloquegis.\nEl teu perfil els sembla així.", - "user_blocking_warning": "No pots veure el perfil de %s\n fins que el desbloquegis.\nEl teu perfil els sembla així.", - "blocked_warning": "No pots veure el perfil d'aquest usuari\nfins que et desbloquegi.", - "user_blocked_warning": "No pots veure el perfil de %s\n fins que et desbloquegi.", + "blocking_warning": "No pots veure el perfil d'aquest usuari\nfins que el desbloquis.\nEl teu perfil els sembla així.", + "user_blocking_warning": "No pots veure el perfil de %s\nfins que el desbloquis.\nEl teu perfil els sembla així.", + "blocked_warning": "No pots veure el perfil d'aquest usuari\nfins que et desbloqui.", + "user_blocked_warning": "No pots veure el perfil de %s\n fins que et desbloqui.", "suspended_warning": "Aquest usuari ha estat suspès.", "user_suspended_warning": "El compte de %s ha estat suspès." } @@ -226,7 +226,7 @@ } }, "server_picker": { - "title": "Mastodon està fet d'usuaris en diferents comunitats.", + "title": "Mastodon està fet d'usuaris en diferents servidors.", "subtitle": "Tria un servidor en funció de la teva regió, interessos o un de propòsit general. Seguiràs podent connectar amb tothom a Mastodon, independentment del servidor.", "button": { "category": { @@ -367,11 +367,11 @@ }, "suggestion_account": { "title": "Cerca Persones a Seguir", - "follow_explain": "Quan segueixes algú, veuràs les seves publicacions a Inici." + "follow_explain": "Quan segueixes algú, veuràs els seus tuts a Inici." }, "compose": { "title": { - "new_post": "Nova publicació", + "new_post": "Nou Tut", "new_reply": "Nova Resposta" }, "media_selection": { @@ -386,8 +386,8 @@ "photo": "foto", "video": "vídeo", "attachment_broken": "Aquest %s està trencat i no pot ser\ncarregat a Mastodon.", - "description_photo": "Descriu la foto per als disminuïts visuals...", - "description_video": "Descriu el vídeo per als disminuïts visuals...", + "description_photo": "Descriu la foto per a les persones amb diversitat funcional...", + "description_video": "Descriu el vídeo per a les persones amb diversitat funcional...", "load_failed": "Ha fallat la càrrega", "upload_failed": "Pujada fallida", "can_not_recognize_this_media_attachment": "No es pot reconèixer aquest adjunt multimèdia", @@ -426,13 +426,13 @@ "custom_emoji_picker": "Selector d'Emoji Personalitzat", "enable_content_warning": "Activa l'Avís de Contingut", "disable_content_warning": "Desactiva l'Avís de Contingut", - "post_visibility_menu": "Menú de Visibilitat de Publicació", - "post_options": "Opcions del tut", + "post_visibility_menu": "Menú de Visibilitat del Tut", + "post_options": "Opcions del Tut", "posting_as": "Publicant com a %s" }, "keyboard": { - "discard_post": "Descarta la Publicació", - "publish_post": "Envia la Publicació", + "discard_post": "Descarta el Tut", + "publish_post": "Envia el Tut", "toggle_poll": "Commuta l'enquesta", "toggle_content_warning": "Commuta l'Avís de Contingut", "append_attachment_entry": "Afegeix Adjunt - %s", @@ -444,7 +444,7 @@ "follows_you": "Et segueix" }, "dashboard": { - "posts": "publicacions", + "posts": "tuts", "following": "seguint", "followers": "seguidors" }, @@ -460,9 +460,9 @@ } }, "segmented_control": { - "posts": "Publicacions", + "posts": "Tuts", "replies": "Respostes", - "posts_and_replies": "Publicacions i Respostes", + "posts_and_replies": "Tuts i Respostes", "media": "Mèdia", "about": "Quant a" }, @@ -476,12 +476,12 @@ "message": "Confirma deixar de silenciar a %s" }, "confirm_block_user": { - "title": "Bloqueja el Compte", - "message": "Confirma per a bloquejar %s" + "title": "Bloca el Compte", + "message": "Confirma per a blocar %s" }, "confirm_unblock_user": { - "title": "Desbloqueja el Compte", - "message": "Confirma per a desbloquejar %s" + "title": "Desbloca el Compte", + "message": "Confirma per a desblocar %s" }, "confirm_show_reblogs": { "title": "Mostra els Impulsos", @@ -541,7 +541,7 @@ "all": "Tots", "people": "Gent", "hashtags": "Etiquetes", - "posts": "Publicacions" + "posts": "Tuts" }, "empty_state": { "no_results": "No hi ha resultats" @@ -552,13 +552,13 @@ }, "discovery": { "tabs": { - "posts": "Publicacions", + "posts": "Tuts", "hashtags": "Etiquetes", "news": "Notícies", "community": "Comunitat", "for_you": "Per a tu" }, - "intro": "Aquestes son les publicacions que criden l'atenció en el teu racó de Mastodon." + "intro": "Aquests son els tuts que criden l'atenció en el teu racó de Mastodon." }, "favorite": { "title": "Els teus Favorits" @@ -588,8 +588,8 @@ } }, "thread": { - "back_title": "Publicació", - "title": "Publicació de %s" + "back_title": "Tut", + "title": "Tut de %s" }, "settings": { "title": "Configuració", @@ -609,9 +609,9 @@ }, "notifications": { "title": "Notificacions", - "favorites": "Ha afavorit el meu estat", + "favorites": "Ha afavorit el meu tut", "follows": "Em segueix", - "boosts": "Ha impulsat el meu estat", + "boosts": "Ha impulsat el meu tut", "mentions": "M'ha mencionat", "trigger": { "anyone": "algú", @@ -653,7 +653,7 @@ "title": "Informa sobre %s", "step1": "Pas 1 de 2", "step2": "Pas 2 de 2", - "content1": "Hi ha alguna altre publicació que vulguis afegir a l'informe?", + "content1": "Hi ha algun altre tut que vulguis afegir a l'informe?", "content2": "Hi ha alguna cosa que els moderadors hagin de saber sobre aquest informe?", "report_sent_title": "Gràcies per informar, ho investigarem.", "send": "Envia Informe", @@ -662,7 +662,7 @@ "reported": "REPORTAT", "step_one": { "step_1_of_4": "Pas 1 de 4", - "whats_wrong_with_this_post": "Quin és el problema amb aquesta publicació?", + "whats_wrong_with_this_post": "Quin és el problema amb aquest tut?", "whats_wrong_with_this_account": "Quin és el problema amb aquest compte?", "whats_wrong_with_this_username": "Quin és el problema amb %s?", "select_the_best_match": "Selecciona la millor coincidència", @@ -683,7 +683,7 @@ }, "step_three": { "step_3_of_4": "Pas 3 de 4", - "are_there_any_posts_that_back_up_this_report": "Hi ha alguna publicació que recolzi aquest informe?", + "are_there_any_posts_that_back_up_this_report": "Hi ha alguns tuts que recolzin aquest informe?", "select_all_that_apply": "Selecciona tot el que correspongui" }, "step_four": { @@ -692,14 +692,14 @@ }, "step_final": { "dont_want_to_see_this": "No vols veure això?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la vostra experiència.", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la teva experiència.", "unfollow": "Deixa de seguir", "unfollowed": "S'ha deixat de seguir", "unfollow_user": "Deixa de seguir %s", "mute_user": "Silencia %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No veuràs les seves publicacions o impulsos a la teva línia de temps personal. No sabran que han estat silenciats.", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No veuràs els seus tuts o impulsos a la teva línia de temps personal. No sabran que han estat silenciats.", "block_user": "Bloca %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats.", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ja no podran seguir ni veure els teus tus, però poden veure si han estat blocats.", "while_we_review_this_you_can_take_action_against_user": "Mentre ho revisem, pots prendre mesures contra %s" } }, From 75b0f1bfb82e9b69de14d2553e5b8353e38755b5 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 22 Nov 2022 13:06:17 -0500 Subject: [PATCH 182/733] Allow pressing escape to close the media viewer --- .../Scene/MediaPreview/MediaPreviewViewController.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index dee6c00ea..7e7a84358 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -359,12 +359,12 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { extension MediaPreviewViewController { - var closeKeyCommand: UIKeyCommand { + func closeKeyCommand(input: String) -> UIKeyCommand { UIKeyCommand( title: L10n.Scene.Preview.Keyboard.closePreview, image: nil, action: #selector(MediaPreviewViewController.closePreviewKeyCommandHandler(_:)), - input: "i", + input: input, modifierFlags: [], propertyList: nil, alternates: [], @@ -408,7 +408,8 @@ extension MediaPreviewViewController { override var keyCommands: [UIKeyCommand] { return [ - closeKeyCommand, + closeKeyCommand(input: UIKeyCommand.inputEscape), + closeKeyCommand(input: "i"), showNextKeyCommand, showPreviousKeyCommand, ] From bcecf7f466bc281f31e2bcd447ff897c4563216d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 21:09:15 +0100 Subject: [PATCH 183/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 898934eb3..ed827e2ed 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Hafan", "search": "Chwilio", - "notifications": "Notifications", + "notifications": "Hysbysiadau", "profile": "Proffil" }, "keyboard": { @@ -367,7 +367,7 @@ }, "suggestion_account": { "title": "Chwilio a Dilyn Pobl", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "follow_explain": "Ar ôl ichi ddilyn rhywun, byddwch yn gweld eu postiadau yn eich ffrwd hafan." }, "compose": { "title": { From 878dddc5c3c130933f262100ff30eeecefdc3e2f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 22:11:34 +0100 Subject: [PATCH 184/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index ed827e2ed..a243dc9c4 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -653,7 +653,7 @@ "title": "Riportio %s", "step1": "Cam 1 o 2", "step2": "Cam 2 o 2", - "content1": "Are there any other posts you’d like to add to the report?", + "content1": "Hoffech chi ychwanegu unrhyw postiadau eraill i'r adroddiad?", "content2": "Is there anything the moderators should know about this report?", "report_sent_title": "Diolch am adrodd, byddwn yn ymchwilio i hyn.", "send": "Anfon adroddiad", @@ -697,10 +697,10 @@ "unfollowed": "Dad-ddilynwyd", "unfollow_user": "Dad-ddilyn %s", "mute_user": "Anwybyddu %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Ni fyddwch yn gweld eu postiadau neu hybiau yn eich ffrwd hafan. Ni fyddant yn gwybod eich bod wedi eu hanwybyddu.", "block_user": "Blocio %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ni fyddant yn gallu eich dilyn neu weld eich postiadau, ond maen nhw'n gallu gweld eich bod wedi'u blocio.", + "while_we_review_this_you_can_take_action_against_user": "Tra byddwn ni'n edrych ar hyn, gallwch gymryd camau yn erbyn %s" } }, "preview": { @@ -711,13 +711,13 @@ } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", + "tab_bar_hint": "Proffil cyfredol: %s. Tapiwch dwywaith a gwasgu i ddefnyddio'r newidiwr cyfrifon", "dismiss_account_switcher": "Diddymu Newidiwr Cyfrifon", "add_account": "Ychwanegu Cyfrif" }, "wizard": { "new_in_mastodon": "Newydd i Mastodon", - "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", + "multiple_account_switch_intro_description": "Newid rhwng cyfrifon gwahanol wrth wasgu'r botwm proffil.", "accessibility_hint": "Tapiwch dwywaith i ddiddymu'r dewin hwn" }, "bookmark": { From 0910baab6c2fa694b314ad88244864364d90f42d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 22 Nov 2022 16:19:18 -0500 Subject: [PATCH 185/733] Allow media viewer to be rotated to any orientation --- .../Scene/MediaPreview/MediaPreviewViewController.swift | 4 ++++ Mastodon/Scene/Root/MainTab/MainTabBarController.swift | 3 +++ Mastodon/Scene/Root/RootSplitViewController.swift | 4 ++++ Mastodon/Supporting Files/AppDelegate.swift | 7 ------- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index dee6c00ea..a14a0dccf 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -165,6 +165,10 @@ extension MediaPreviewViewController { !viewModel.showingChrome } + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .all + } + } extension MediaPreviewViewController { diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 2e5d5ae58..70e1455c3 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -369,6 +369,9 @@ extension MainTabBarController { updateAvatarButtonAppearance() } + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all + } } extension MainTabBarController { diff --git a/Mastodon/Scene/Root/RootSplitViewController.swift b/Mastodon/Scene/Root/RootSplitViewController.swift index 0b6f4f97a..5332140db 100644 --- a/Mastodon/Scene/Root/RootSplitViewController.swift +++ b/Mastodon/Scene/Root/RootSplitViewController.swift @@ -112,6 +112,10 @@ extension RootSplitViewController { self.updateBehavior(size: size) } + + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all + } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) diff --git a/Mastodon/Supporting Files/AppDelegate.swift b/Mastodon/Supporting Files/AppDelegate.swift index 84b819a5c..85fed2b28 100644 --- a/Mastodon/Supporting Files/AppDelegate.swift +++ b/Mastodon/Supporting Files/AppDelegate.swift @@ -64,13 +64,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } extension AppDelegate { - func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { - return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all - } -} - -extension AppDelegate { - func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { appContext.notificationService.deviceToken.value = deviceToken } From b62650883345ae3611500027d540297af0a9fa6f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Nov 2022 23:10:33 +0100 Subject: [PATCH 186/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index c04478f78..e0e566ceb 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -512,10 +512,10 @@ "followed_by_names": "Followed by %s" }, "favorited_by": { - "title": "Favorited By" + "title": "お気に入り" }, "reblogged_by": { - "title": "Reblogged By" + "title": "ブースト" }, "search": { "title": "検索", From a45fa65802761f9bb43b993813fb2f4a8b771b09 Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 23 Nov 2022 12:27:46 +0800 Subject: [PATCH 187/733] chore: set minimal size limit for photo to 1MiB --- .../Attachment/AttachmentViewModel+Compress.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift index 6df22d324..417bc773a 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift @@ -97,7 +97,7 @@ extension AttachmentViewModel { extension AttachmentViewModel { @AttachmentViewModelActor func compressImage(data: Data, sizeLimit: SizeLimit) throws -> Output { - let maxPayloadSizeInBytes = sizeLimit.image ?? 10 * 1024 * 1024 + let maxPayloadSizeInBytes = max((sizeLimit.image ?? 10 * 1024 * 1024), 1 * 1024 * 1024) guard let image = KFCrossPlatformImage(data: data)?.kf.normalized, var imageData = image.kf.pngRepresentation() From 366287a9f84eca283fe7a9295774548ae5456b76 Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 23 Nov 2022 14:16:28 +0800 Subject: [PATCH 188/733] fix: use singleton AppContext to workaround reentry problem --- MastodonSDK/Sources/MastodonCore/AppContext.swift | 4 ++++ ShareActionExtension/Scene/ShareViewController.swift | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/AppContext.swift b/MastodonSDK/Sources/MastodonCore/AppContext.swift index d44c1ea5a..d8aa06fae 100644 --- a/MastodonSDK/Sources/MastodonCore/AppContext.swift +++ b/MastodonSDK/Sources/MastodonCore/AppContext.swift @@ -115,6 +115,10 @@ public class AppContext: ObservableObject { .store(in: &disposeBag) } + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + } extension AppContext { diff --git a/ShareActionExtension/Scene/ShareViewController.swift b/ShareActionExtension/Scene/ShareViewController.swift index 4a093becd..00c5b77de 100644 --- a/ShareActionExtension/Scene/ShareViewController.swift +++ b/ShareActionExtension/Scene/ShareViewController.swift @@ -21,7 +21,7 @@ final class ShareViewController: UIViewController { var disposeBag = Set() - let context = AppContext() + let context = AppContext.shared private(set) lazy var viewModel = ShareViewModel(context: context) let publishButton: UIButton = { @@ -63,6 +63,10 @@ final class ShareViewController: UIViewController { label.text = "No Available Account" // TODO: i18n return label }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } } @@ -155,7 +159,7 @@ extension ShareViewController { _ = try await statusPublisher.publish(api: context.apiService, authContext: authContext) self.publishButton.setTitle(L10n.Common.Controls.Actions.done, for: .normal) - try await Task.sleep(nanoseconds: 1 * .second) + try await Task.sleep(nanoseconds: 1 * .second) self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) @@ -325,3 +329,7 @@ extension ShareViewController { case missingAuthentication } } + +extension AppContext { + static let shared = AppContext() +} From df6b5055e8e7afe37b152bae385041bacf2386c3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 23 Nov 2022 07:46:26 +0100 Subject: [PATCH 189/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 88d93b2fa..c688673e0 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Bảng tin", "search": "Tìm kiếm", - "notifications": "Notifications", + "notifications": "Thông báo", "profile": "Trang hồ sơ" }, "keyboard": { From a4cab15d86cc2f4bfafc85843e3a1fdf77afc8cc Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Wed, 23 Nov 2022 19:03:54 -0800 Subject: [PATCH 190/733] Make it compile --- .../xcshareddata/swiftpm/Package.resolved | 33 +++++++------------ .../View/Content/LinkPreviewButton.swift | 1 - 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0a62cc7f5..26b58956b 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Alamofire/Alamofire.git", "state" : { - "revision" : "354dda32d89fc8cd4f5c46487f64957d355f53d8", - "version" : "5.6.1" + "revision" : "78424be314842833c04bc3bef5b72e85fff99204", + "version" : "5.6.4" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Flipboard/FLAnimatedImage.git", "state" : { - "revision" : "e7f9fd4681ae41bf6f3056db08af4f401d61da52", - "version" : "1.0.16" + "revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f", + "version" : "1.0.17" } }, { @@ -104,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/kean/Nuke.git", "state" : { - "revision" : "0ea7545b5c918285aacc044dc75048625c8257cc", - "version" : "10.8.0" + "revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97", + "version" : "10.11.2" } }, { @@ -117,22 +117,13 @@ "version" : "8.0.0" } }, - { - "identity" : "opengraph", - "kind" : "remoteSourceControl", - "location" : "https://github.com/satoshi-takano/OpenGraph", - "state" : { - "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", - "version" : "1.5.0" - } - }, { "identity" : "pageboy", "kind" : "remoteSourceControl", "location" : "https://github.com/uias/Pageboy", "state" : { - "revision" : "34ecb6e7c4e0e07494960ab2f7cc9a02293915a6", - "version" : "3.6.2" + "revision" : "af8fa81788b893205e1ff42ddd88c5b0b315d7c5", + "version" : "3.7.0" } }, { @@ -149,8 +140,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SDWebImage/SDWebImage.git", "state" : { - "revision" : "2e63d0061da449ad0ed130768d05dceb1496de44", - "version" : "5.12.5" + "revision" : "3312bf5e67b52fbce7c3caf431b0cda721a9f7bb", + "version" : "5.14.2" } }, { @@ -194,8 +185,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/scinfu/SwiftSoup.git", "state" : { - "revision" : "41e7c263fb8c277e980ebcb9b0b5f6031d3d4886", - "version" : "2.4.2" + "revision" : "6778575285177365cbad3e5b8a72f2a20583cfec", + "version" : "2.4.3" } }, { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index 344511217..94de42ddc 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -9,7 +9,6 @@ import AlamofireImage import LinkPresentation import MastodonAsset import MastodonCore -import OpenGraph import UIKit public final class LinkPreviewButton: UIControl { From 595b46e96e10f8d16656949629ee6c2947fd3b36 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Wed, 23 Nov 2022 20:03:45 -0800 Subject: [PATCH 191/733] Add card persistence --- .../CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData 5.xcdatamodel/contents | 271 ++++++++++++++++++ .../CoreDataStack/Entity/Mastodon/Card.swift | 162 +++++++++++ .../Entity/Mastodon/Status.swift | 10 +- .../Entity/Transient/MastodonCardType.swift | 34 +++ .../Persistence/Persistence+Card.swift | 94 ++++++ .../Persistence/Persistence+Status.swift | 18 +- .../Persistence/Persistence.swift | 1 + 8 files changed, 587 insertions(+), 5 deletions(-) create mode 100644 MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents create mode 100644 MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift create mode 100644 MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonCardType.swift create mode 100644 MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index 1d5ea989f..2145ac780 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 4.xcdatamodel + CoreData 5.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents new file mode 100644 index 000000000..5a0ef6a6a --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift new file mode 100644 index 000000000..12f6d636e --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift @@ -0,0 +1,162 @@ +// +// Card.swift +// CoreDataStack +// +// Created by Kyle Bashour on 11/23/22. +// + +import Foundation +import CoreData + +public final class Card: NSManagedObject { + // sourcery: autoGenerateProperty + @NSManaged public private(set) var url: String + // sourcery: autoGenerateProperty + @NSManaged public private(set) var title: String + // sourcery: autoGenerateProperty + @NSManaged public private(set) var desc: String + + @NSManaged public private(set) var typeRaw: String + // sourcery: autoGenerateProperty + public var type: MastodonCardType { + get { MastodonCardType(rawValue: typeRaw) } + set { typeRaw = newValue.rawValue } + } + + // sourcery: autoGenerateProperty + @NSManaged public private(set) var authorName: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var authorURL: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var providerName: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var providerURL: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var width: Int64 + // sourcery: autoGenerateProperty + @NSManaged public private(set) var height: Int64 + // sourcery: autoGenerateProperty + @NSManaged public private(set) var image: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var embedURL: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var blurhash: String? + + // one-to-one relationship + @NSManaged public private(set) var status: Status +} + +extension Card { + + @discardableResult + public static func insert( + into context: NSManagedObjectContext, + property: Property + ) -> Card { + let object: Card = context.insertObject() + + object.configure(property: property) + + return object + } + +} + +extension Card: Managed { + public static var defaultSortDescriptors: [NSSortDescriptor] { + return [] + } +} + +// MARK: - AutoGenerateProperty +extension Card: AutoGenerateProperty { + // sourcery:inline:Card.AutoGenerateProperty + + // Generated using Sourcery + // DO NOT EDIT + public struct Property { + public let url: String + public let title: String + public let desc: String + public let type: MastodonCardType + public let authorName: String? + public let authorURL: String? + public let providerName: String? + public let providerURL: String? + public let width: Int64 + public let height: Int64 + public let image: String? + public let embedURL: String? + public let blurhash: String? + + public init( + url: String, + title: String, + desc: String, + type: MastodonCardType, + authorName: String?, + authorURL: String?, + providerName: String?, + providerURL: String?, + width: Int64, + height: Int64, + image: String?, + embedURL: String?, + blurhash: String? + ) { + self.url = url + self.title = title + self.desc = desc + self.type = type + self.authorName = authorName + self.authorURL = authorURL + self.providerName = providerName + self.providerURL = providerURL + self.width = width + self.height = height + self.image = image + self.embedURL = embedURL + self.blurhash = blurhash + } + } + + public func configure(property: Property) { + self.url = property.url + self.title = property.title + self.desc = property.desc + self.type = property.type + self.authorName = property.authorName + self.authorURL = property.authorURL + self.providerName = property.providerName + self.providerURL = property.providerURL + self.width = property.width + self.height = property.height + self.image = property.image + self.embedURL = property.embedURL + self.blurhash = property.blurhash + } + + public func update(property: Property) { + } + + // sourcery:end +} + +// MARK: - AutoGenerateRelationship +extension Card: AutoGenerateRelationship { + // sourcery:inline:Card.AutoGenerateRelationship + + // Generated using Sourcery + // DO NOT EDIT + public struct Relationship { + + public init( + ) { + } + } + + public func configure(relationship: Relationship) { + } + + // sourcery:end +} diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift index 0c7291913..1bc641f5f 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift @@ -84,7 +84,9 @@ public final class Status: NSManagedObject { @NSManaged public private(set) var pinnedBy: MastodonUser? // sourcery: autoGenerateRelationship @NSManaged public private(set) var poll: Poll? - + // sourcery: autoGenerateRelationship + @NSManaged public private(set) var card: Card? + // one-to-many relationship @NSManaged public private(set) var feeds: Set @@ -379,15 +381,18 @@ extension Status: AutoGenerateRelationship { public let author: MastodonUser public let reblog: Status? public let poll: Poll? + public let card: Card? public init( author: MastodonUser, reblog: Status?, - poll: Poll? + poll: Poll?, + card: Card? ) { self.author = author self.reblog = reblog self.poll = poll + self.card = card } } @@ -395,6 +400,7 @@ extension Status: AutoGenerateRelationship { self.author = relationship.author self.reblog = relationship.reblog self.poll = relationship.poll + self.card = relationship.card } // sourcery:end } diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonCardType.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonCardType.swift new file mode 100644 index 000000000..59401cf4a --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Transient/MastodonCardType.swift @@ -0,0 +1,34 @@ +// +// MastodonCardType.swift +// CoreDataStack +// +// Created by Kyle Bashour on 11/23/22. +// + +import Foundation + +public enum MastodonCardType: RawRepresentable, Equatable { + case link + case photo + case video + + case _other(String) + + public init(rawValue: String) { + switch rawValue { + case "link": self = .link + case "photo": self = .photo + case "video": self = .video + default: self = ._other(rawValue) + } + } + + public var rawValue: String { + switch self { + case .link: return "link" + case .photo: return "photo" + case .video: return "video" + case ._other(let value): return value + } + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift new file mode 100644 index 000000000..8c3b4c312 --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift @@ -0,0 +1,94 @@ +// +// Persistence+Card.swift +// +// +// Created by MainasuK on 2021-12-9. +// + +import CoreData +import CoreDataStack +import Foundation +import MastodonSDK +import os.log + +extension Persistence.Card { + + public struct PersistContext { + public let domain: String + public let entity: Mastodon.Entity.Card + public let me: MastodonUser? + public let log = Logger(subsystem: "Card", category: "Persistence") + public init( + domain: String, + entity: Mastodon.Entity.Card, + me: MastodonUser? + ) { + self.domain = domain + self.entity = entity + self.me = me + } + } + + public struct PersistResult { + public let card: Card + public let isNewInsertion: Bool + + public init( + card: Card, + isNewInsertion: Bool + ) { + self.card = card + self.isNewInsertion = isNewInsertion + } + + #if DEBUG + public let logger = Logger(subsystem: "Persistence.MastodonCard.PersistResult", category: "Persist") + public func log() { + let pollInsertionFlag = isNewInsertion ? "+" : "-" + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(pollInsertionFlag)](\(card.title)):") + } + #endif + } + + public static func create( + in managedObjectContext: NSManagedObjectContext, + context: PersistContext + ) -> PersistResult { + var type: MastodonCardType { + switch context.entity.type { + case .link: return .link + case .photo: return .photo + case .video: return .video + case .rich: return ._other(context.entity.type.rawValue) + case ._other(let rawValue): return ._other(rawValue) + } + } + + let property = Card.Property( + url: context.entity.url, + title: context.entity.title, + desc: context.entity.description, + type: type, + authorName: context.entity.authorName, + authorURL: context.entity.authorURL, + providerName: context.entity.providerName, + providerURL: context.entity.providerURL, + width: Int64(context.entity.width ?? 0), + height: Int64(context.entity.height ?? 0), + image: context.entity.image, + embedURL: context.entity.embedURL, + blurhash: context.entity.blurhash + ) + + let card = Card.insert( + into: managedObjectContext, + property: property + ) + + return PersistResult( + card: card, + isNewInsertion: true + ) + } + +} diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift index a15e974e4..97ab32e30 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift @@ -107,7 +107,20 @@ extension Persistence.Status { ) return result.poll }() - + + let card: Card? = { + guard let entity = context.entity.card else { return nil } + let result = Persistence.Card.create( + in: managedObjectContext, + context: Persistence.Card.PersistContext( + domain: context.domain, + entity: entity, + me: context.me + ) + ) + return result.card + }() + let authorResult = Persistence.MastodonUser.createOrMerge( in: managedObjectContext, context: Persistence.MastodonUser.PersistContext( @@ -122,7 +135,8 @@ extension Persistence.Status { let relationship = Status.Relationship( author: author, reblog: reblog, - poll: poll + poll: poll, + card: card ) let status = create( in: managedObjectContext, diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence.swift index 350b603cc..3a36dec41 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence.swift @@ -15,6 +15,7 @@ extension Persistence { public enum MastodonUser { } public enum Status { } public enum Poll { } + public enum Card { } public enum PollOption { } public enum Tag { } public enum SearchHistory { } From f8d1afc7e47255cbd1adc420eb25465a1f80fead Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Wed, 23 Nov 2022 21:51:39 -0800 Subject: [PATCH 192/733] Working pretty well --- .../CoreData 5.xcdatamodel/contents | 8 +- .../CoreDataStack/Entity/Mastodon/Card.swift | 48 +++++---- .../Persistence/Persistence+Card.swift | 8 +- .../View/Content/LinkPreviewButton.swift | 98 +++++++++---------- .../Content/StatusView+Configuration.swift | 20 ++++ .../View/Content/StatusView+ViewModel.swift | 30 +++--- 6 files changed, 119 insertions(+), 93 deletions(-) diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents index 5a0ef6a6a..c18d7492b 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -9,17 +9,17 @@ - + - + - + - + diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift index 12f6d636e..99f53f268 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift @@ -10,7 +10,11 @@ import CoreData public final class Card: NSManagedObject { // sourcery: autoGenerateProperty - @NSManaged public private(set) var url: String + @NSManaged public private(set) var urlRaw: String + public var url: URL? { + URL(string: urlRaw) + } + // sourcery: autoGenerateProperty @NSManaged public private(set) var title: String // sourcery: autoGenerateProperty @@ -26,19 +30,23 @@ public final class Card: NSManagedObject { // sourcery: autoGenerateProperty @NSManaged public private(set) var authorName: String? // sourcery: autoGenerateProperty - @NSManaged public private(set) var authorURL: String? + @NSManaged public private(set) var authorURLRaw: String? // sourcery: autoGenerateProperty @NSManaged public private(set) var providerName: String? // sourcery: autoGenerateProperty - @NSManaged public private(set) var providerURL: String? + @NSManaged public private(set) var providerURLRaw: String? // sourcery: autoGenerateProperty @NSManaged public private(set) var width: Int64 // sourcery: autoGenerateProperty @NSManaged public private(set) var height: Int64 // sourcery: autoGenerateProperty @NSManaged public private(set) var image: String? + public var imageURL: URL? { + image.flatMap(URL.init) + } + // sourcery: autoGenerateProperty - @NSManaged public private(set) var embedURL: String? + @NSManaged public private(set) var embedURLRaw: String? // sourcery: autoGenerateProperty @NSManaged public private(set) var blurhash: String? @@ -75,64 +83,64 @@ extension Card: AutoGenerateProperty { // Generated using Sourcery // DO NOT EDIT public struct Property { - public let url: String + public let urlRaw: String public let title: String public let desc: String public let type: MastodonCardType public let authorName: String? - public let authorURL: String? + public let authorURLRaw: String? public let providerName: String? - public let providerURL: String? + public let providerURLRaw: String? public let width: Int64 public let height: Int64 public let image: String? - public let embedURL: String? + public let embedURLRaw: String? public let blurhash: String? public init( - url: String, + urlRaw: String, title: String, desc: String, type: MastodonCardType, authorName: String?, - authorURL: String?, + authorURLRaw: String?, providerName: String?, - providerURL: String?, + providerURLRaw: String?, width: Int64, height: Int64, image: String?, - embedURL: String?, + embedURLRaw: String?, blurhash: String? ) { - self.url = url + self.urlRaw = urlRaw self.title = title self.desc = desc self.type = type self.authorName = authorName - self.authorURL = authorURL + self.authorURLRaw = authorURLRaw self.providerName = providerName - self.providerURL = providerURL + self.providerURLRaw = providerURLRaw self.width = width self.height = height self.image = image - self.embedURL = embedURL + self.embedURLRaw = embedURLRaw self.blurhash = blurhash } } public func configure(property: Property) { - self.url = property.url + self.urlRaw = property.urlRaw self.title = property.title self.desc = property.desc self.type = property.type self.authorName = property.authorName - self.authorURL = property.authorURL + self.authorURLRaw = property.authorURLRaw self.providerName = property.providerName - self.providerURL = property.providerURL + self.providerURLRaw = property.providerURLRaw self.width = property.width self.height = property.height self.image = property.image - self.embedURL = property.embedURL + self.embedURLRaw = property.embedURLRaw self.blurhash = property.blurhash } diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift index 8c3b4c312..838d5e128 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift @@ -65,18 +65,18 @@ extension Persistence.Card { } let property = Card.Property( - url: context.entity.url, + urlRaw: context.entity.url, title: context.entity.title, desc: context.entity.description, type: type, authorName: context.entity.authorName, - authorURL: context.entity.authorURL, + authorURLRaw: context.entity.authorURL, providerName: context.entity.providerName, - providerURL: context.entity.providerURL, + providerURLRaw: context.entity.providerURL, width: Int64(context.entity.width ?? 0), height: Int64(context.entity.height ?? 0), image: context.entity.image, - embedURL: context.entity.embedURL, + embedURLRaw: context.entity.embedURL, blurhash: context.entity.blurhash ) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index 94de42ddc..4cb2dca6d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -9,18 +9,26 @@ import AlamofireImage import LinkPresentation import MastodonAsset import MastodonCore +import CoreDataStack import UIKit public final class LinkPreviewButton: UIControl { - private var linkPresentationTask: Task? - private var url: URL? - private let containerStackView = UIStackView() private let labelStackView = UIStackView() private let imageView = UIImageView() private let titleLabel = UILabel() - private let subtitleLabel = UILabel() + private let linkLabel = UILabel() + + private lazy var compactImageConstraints = [ + imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), + imageView.heightAnchor.constraint(equalTo: heightAnchor), + containerStackView.heightAnchor.constraint(equalToConstant: 85), + ] + + private lazy var largeImageConstraints = [ + imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40), + ] public override init(frame: CGRect) { super.init(frame: frame) @@ -29,25 +37,24 @@ public final class LinkPreviewButton: UIControl { layer.cornerCurve = .continuous layer.cornerRadius = 10 layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor - backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor titleLabel.numberOfLines = 2 titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) titleLabel.text = "This is where I'd put a title... if I had one" titleLabel.textColor = Asset.Colors.Label.primary.color - subtitleLabel.text = "Subtitle" - subtitleLabel.numberOfLines = 1 - subtitleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) - subtitleLabel.textColor = Asset.Colors.Label.secondary.color - subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20) + linkLabel.text = "Subtitle" + linkLabel.numberOfLines = 1 + linkLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) + linkLabel.textColor = Asset.Colors.Label.secondary.color - imageView.backgroundColor = UIColor.black.withAlphaComponent(0.15) + imageView.tintColor = Asset.Colors.Label.secondary.color + imageView.backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true + labelStackView.addArrangedSubview(linkLabel) labelStackView.addArrangedSubview(titleLabel) - labelStackView.addArrangedSubview(subtitleLabel) labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10) labelStackView.isLayoutMarginsRelativeArrangement = true labelStackView.axis = .vertical @@ -55,20 +62,16 @@ public final class LinkPreviewButton: UIControl { containerStackView.addArrangedSubview(imageView) containerStackView.addArrangedSubview(labelStackView) containerStackView.distribution = .fill - containerStackView.alignment = .center addSubview(containerStackView) containerStackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - containerStackView.heightAnchor.constraint(equalToConstant: 85), containerStackView.topAnchor.constraint(equalTo: topAnchor), containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor), containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor), containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor), - imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), - imageView.heightAnchor.constraint(equalTo: heightAnchor), ]) } @@ -76,36 +79,32 @@ public final class LinkPreviewButton: UIControl { fatalError("init(coder:) has not been implemented") } - public func configure(url: URL, trimmed: String) { - guard url != self.url else { - return + public func configure(card: Card) { + let isCompact = card.width == card.height + + titleLabel.text = card.title + linkLabel.text = card.url?.host + imageView.contentMode = .center + + imageView.sd_setImage( + with: card.imageURL, + placeholderImage: isCompact ? newsIcon : photoIcon + ) { [weak imageView] image, _, _, _ in + if image != nil { + imageView?.contentMode = .scaleAspectFill + } } - reset() - subtitleLabel.text = trimmed - self.url = url + NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints) - linkPresentationTask = Task { - do { - let metadata = try await LPMetadataProvider().startFetchingMetadata(for: url) - - guard !Task.isCancelled else { - return - } - - self.titleLabel.text = metadata.title - if let result = try await metadata.imageProvider?.loadImageData() { - let image = UIImage(data: result.data) - - guard !Task.isCancelled else { - return - } - - self.imageView.image = image - } - } catch { - self.subtitleLabel.text = "Error loading link preview" - } + if isCompact { + containerStackView.alignment = .center + containerStackView.axis = .horizontal + NSLayoutConstraint.activate(compactImageConstraints) + } else { + containerStackView.alignment = .fill + containerStackView.axis = .vertical + NSLayoutConstraint.activate(largeImageConstraints) } } @@ -117,11 +116,12 @@ public final class LinkPreviewButton: UIControl { } } - private func reset() { - linkPresentationTask?.cancel() - url = nil - imageView.image = nil - titleLabel.text = nil - subtitleLabel.text = nil + private var newsIcon: UIImage? { + UIImage(systemName: "newspaper.fill") + } + + private var photoIcon: UIImage? { + let configuration = UIImage.SymbolConfiguration(pointSize: 40) + return UIImage(systemName: "photo", withConfiguration: configuration) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 47e4f18ff..fb28d564d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -40,6 +40,14 @@ extension StatusView { extension StatusView { public func configure(status: Status) { + if let card = status.card { + print("---- \(card.title)") + print("---- \(card.url)") + print("---- \(card.image)") + print("---- \(card.width)") + print("---- \(card.height)") + } + viewModel.objects.insert(status) if let reblog = status.reblog { viewModel.objects.insert(reblog) @@ -53,6 +61,7 @@ extension StatusView { configureContent(status: status) configureMedia(status: status) configurePoll(status: status) + configureCard(status: status) configureToolbar(status: status) configureFilter(status: status) } @@ -349,6 +358,17 @@ extension StatusView { .assign(to: \.isVoting, on: viewModel) .store(in: &disposeBag) } + + private func configureCard(status: Status) { + let status = status.reblog ?? status + if viewModel.mediaViewConfigurations.isEmpty { + status.publisher(for: \.card) + .assign(to: \.card, on: viewModel) + .store(in: &disposeBag) + } else { + viewModel.card = nil + } + } private func configureToolbar(status: Status) { let status = status.reblog ?? status diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index dc3f840f8..e56d82aff 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -69,7 +69,10 @@ extension StatusView { @Published public var voteCount = 0 @Published public var expireAt: Date? @Published public var expired: Bool = false - + + // Card + @Published public var card: Card? + // Visibility @Published public var visibility: MastodonVisibility = .public @@ -185,6 +188,7 @@ extension StatusView.ViewModel { bindContent(statusView: statusView) bindMedia(statusView: statusView) bindPoll(statusView: statusView) + bindCard(statusView: statusView) bindToolbar(statusView: statusView) bindMetric(statusView: statusView) bindMenu(statusView: statusView) @@ -306,21 +310,6 @@ extension StatusView.ViewModel { statusView.contentMetaText.textView.accessibilityTraits = [.staticText] statusView.contentMetaText.textView.accessibilityElementsHidden = false - if let url = content.entities.first(where: { - switch $0.meta { - case .url: - return true - default: - return false - } - }) { - guard case .url(let text, let trimmed, let url, _) = url.meta, let url = URL(string: url) else { - fatalError() - } - - statusView.linkPreviewButton.configure(url: url, trimmed: trimmed) - statusView.setLinkPreviewButtonDisplay() - } } else { statusView.contentMetaText.reset() statusView.contentMetaText.textView.accessibilityLabel = "" @@ -496,6 +485,15 @@ extension StatusView.ViewModel { .assign(to: \.isEnabled, on: statusView.pollVoteButton) .store(in: &disposeBag) } + + private func bindCard(statusView: StatusView) { + $card.sink { card in + guard let card = card else { return } + statusView.linkPreviewButton.configure(card: card) + statusView.setLinkPreviewButtonDisplay() + } + .store(in: &disposeBag) + } private func bindToolbar(statusView: StatusView) { $replyCount From 7819174f89667a219cc4dcadc55d86f6e53f8f36 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:18:57 +0100 Subject: [PATCH 193/733] New translations app.json (Japanese) --- .../StringsConvertor/input/ja.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index e0e566ceb..3d3bd173c 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -187,8 +187,8 @@ "unmute_user": "%sのミュートを解除", "muted": "ミュート済み", "edit_info": "編集", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "ブーストを表示", + "hide_reblogs": "ブーストを非表示" }, "timeline": { "filtered": "フィルター済み", @@ -484,12 +484,12 @@ "message": "%sのブロックを解除しますか?" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "ブーストを表示", + "message": "ブーストを表示しますか?" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "ブーストを非表示", + "message": "ブーストを非表示にしますか?" } }, "accessibility": { From 4ebd4cd709a2c7bdfcbf1160cecea593cee8a66c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:18:58 +0100 Subject: [PATCH 194/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 98537abbe..f74c75545 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Beranda", "search": "Cari", - "notifications": "Notifications", + "notifications": "Notifikasi", "profile": "Profil" }, "keyboard": { @@ -348,8 +348,8 @@ "open_email_app": { "title": "Periksa kotak masuk Anda.", "description": "Kami baru saja mengirimkan Anda sebuah surel. Periksa folder junk Anda jika Anda belum memeriksanya.", - "mail": "Mail", - "open_email_client": "Open Email Client" + "mail": "Pesan", + "open_email_client": "Buka Email Klien" } }, "home_timeline": { @@ -431,8 +431,8 @@ "posting_as": "Posting as %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", + "discard_post": "Hapus Postingan", + "publish_post": "Publikasikan Postingan", "toggle_poll": "Toggle Poll", "toggle_content_warning": "Toggle Content Warning", "append_attachment_entry": "Tambahkan Lampiran - %s", @@ -449,20 +449,20 @@ "followers": "pengikut" }, "fields": { - "add_row": "Add Row", + "add_row": "Tambah Baris", "placeholder": { "label": "Label", "content": "Isi" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Verifikasi %s", + "long": "Kepemilikan tautan ini dapat dicek pada %s" } }, "segmented_control": { "posts": "Postingan", "replies": "Balasan", - "posts_and_replies": "Posts and Replies", + "posts_and_replies": "Kirim dan Balas", "media": "Media", "about": "Tentang" }, @@ -473,7 +473,7 @@ }, "confirm_unmute_user": { "title": "Berhenti Membisukan Akun", - "message": "Confirm to unmute %s" + "message": "Konfirmasi untuk membisukan %s" }, "confirm_block_user": { "title": "Blokir Akun", @@ -494,7 +494,7 @@ }, "accessibility": { "show_avatar_image": "Tampilkan gambar avatar", - "edit_avatar_image": "Edit avatar image", + "edit_avatar_image": "Ubah gambar avatar", "show_banner_image": "Show banner image", "double_tap_to_open_the_list": "Ketuk ganda untuk membuka daftar" } @@ -509,7 +509,7 @@ }, "familiarFollowers": { "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "followed_by_names": "Diikuti oleh %s" }, "favorited_by": { "title": "Favorited By" @@ -546,22 +546,22 @@ "empty_state": { "no_results": "Tidak ada hasil" }, - "recent_search": "Recent searches", + "recent_search": "Pencarian terbaru", "clear": "Hapus" } }, "discovery": { "tabs": { "posts": "Posts", - "hashtags": "Hashtags", - "news": "News", - "community": "Community", - "for_you": "For You" + "hashtags": "Tagar", + "news": "Berita", + "community": "Komunitas", + "for_you": "Untuk Anda" }, "intro": "These are the posts gaining traction in your corner of Mastodon." }, "favorite": { - "title": "Your Favorites" + "title": "Favorit Anda" }, "notification": { "title": { From d96743992338c0d410b7ac1da67bb799995f01ed Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:19:00 +0100 Subject: [PATCH 195/733] New translations Localizable.stringsdict (Indonesian) --- .../input/id.lproj/Localizable.stringsdict | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict index 7e88bdf69..5f80eb15a 100644 --- a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict @@ -13,7 +13,7 @@ NSStringFormatValueTypeKey ld other - %ld unread notifications + %ld notifikasi belum dibaca a11y.plural.count.input_limit_exceeds @@ -47,7 +47,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + tersisa %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -55,7 +55,7 @@ NSStringFormatValueTypeKey ld other - %ld characters + %ld karakter plural.count.followed_by_and_mutual @@ -162,7 +162,7 @@ NSStringFormatValueTypeKey ld other - %ld replies + %ld balasan plural.count.vote @@ -204,7 +204,7 @@ NSStringFormatValueTypeKey ld other - %ld people talking + %ld obrolan plural.count.following @@ -218,7 +218,7 @@ NSStringFormatValueTypeKey ld other - %ld following + %ld mengikuti plural.count.follower From 7be6959ffeb6a80ef7fd410bc7e6d01a5c1a5331 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:19:01 +0100 Subject: [PATCH 196/733] New translations ios-infoPlist.json (Indonesian) --- .../StringsConvertor/input/id.lproj/ios-infoPlist.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json index 0dde7c29e..77bf594c3 100644 --- a/Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NSCameraUsageDescription": "Gunakan untuk mengambil foto untuk postingan status", + "NSPhotoLibraryAddUsageDescription": "Gunakan untuk menyimpan foto ke dalam Galeri Foto", "NewPostShortcutItemTitle": "Postingan Baru", "SearchShortcutItemTitle": "Cari" } From 064cc5740a0dca293935540781e697e908466b78 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:19:03 +0100 Subject: [PATCH 197/733] New translations Intents.strings (Indonesian) --- .../Intents/input/id.lproj/Intents.strings | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings index aa86f7bde..e5376e35e 100644 --- a/Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings @@ -4,13 +4,13 @@ "CsR7G2" = "Buat Postingan di Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Konten apa yang ingin diposting?"; "HdGikU" = "Gagal memposting"; "KDNTJ4" = "Alasan Kegagalan"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Kirim Postingan dengan konten berupa teks"; "RxSqsb" = "Postingan"; @@ -24,9 +24,9 @@ "Zo4jgJ" = "Visibilitas Postingan"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Tidak ada ${count} opsi yang cocok dengan 'Publik'."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Tidak ada ${count} opsi yang cocok dengan 'Untuk Pengikut Saja'."; "ayoYEb-dYQ5NN" = "${content}, Publik"; From 283cbf44cfe471c63a1a493e4527acd8ab04a4f1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 11:19:04 +0100 Subject: [PATCH 198/733] New translations Intents.stringsdict (Indonesian) --- .../Intents/input/id.lproj/Intents.stringsdict | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict index a14f8b9ff..61779d15c 100644 --- a/Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + Ada %#@count_option@ yang cocok dengan ${content}. count_option NSStringFormatSpecTypeKey @@ -13,13 +13,13 @@ NSStringFormatValueTypeKey %ld other - %ld options + %ld opsi There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Ada %#@count_option@ yang cocok dengan ${visibility}. count_option NSStringFormatSpecTypeKey @@ -27,7 +27,7 @@ NSStringFormatValueTypeKey %ld other - %ld options + %ld opsi From ba7955bdb5cf49cdfde49cc108544991c5c74535 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Thu, 24 Nov 2022 07:48:07 -0800 Subject: [PATCH 199/733] Handle taps --- .../Provider/DataSourceFacade+Meta.swift | 18 ++---- .../Provider/DataSourceFacade+URL.swift | 32 +++++++++++ ...er+NotificationTableViewCellDelegate.swift | 55 +++++++++++++++++++ ...Provider+StatusTableViewCellDelegate.swift | 31 ++++++++++- .../NotificationTableViewCellDelegate.swift | 10 ++++ .../StatusTableViewCellDelegate.swift | 5 ++ .../View/Content/LinkPreviewButton.swift | 20 ++++++- .../View/Content/NotificationView.swift | 14 ++++- .../MastodonUI/View/Content/StatusView.swift | 15 ++++- 9 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 Mastodon/Protocol/Provider/DataSourceFacade+URL.swift diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift index dd3c4903a..ca3bbd474 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift @@ -48,18 +48,12 @@ extension DataSourceFacade { assertionFailure() return } - let domain = provider.authContext.mastodonAuthenticationBox.domain - if url.host == domain, - url.pathComponents.count >= 4, - url.pathComponents[0] == "/", - url.pathComponents[1] == "web", - url.pathComponents[2] == "statuses" { - let statusID = url.pathComponents[3] - let threadViewModel = RemoteThreadViewModel(context: provider.context, authContext: provider.authContext, statusID: statusID) - _ = await provider.coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) - } else { - _ = await provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) - } + + await responseToURLAction( + provider: provider, + status: status, + url: url + ) case .hashtag(_, let hashtag, _): let hashtagTimelineViewModel = HashtagTimelineViewModel(context: provider.context, authContext: provider.authContext, hashtag: hashtag) _ = await provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift b/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift new file mode 100644 index 000000000..a65de9537 --- /dev/null +++ b/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift @@ -0,0 +1,32 @@ +// +// DataSourceFacade+URL.swift +// Mastodon +// +// Created by Kyle Bashour on 11/24/22. +// + +import Foundation +import CoreDataStack +import MetaTextKit +import MastodonCore + +extension DataSourceFacade { + static func responseToURLAction( + provider: DataSourceProvider & AuthContextProvider, + status: ManagedObjectRecord, + url: URL + ) async { + let domain = provider.authContext.mastodonAuthenticationBox.domain + if url.host == domain, + url.pathComponents.count >= 4, + url.pathComponents[0] == "/", + url.pathComponents[1] == "web", + url.pathComponents[2] == "statuses" { + let statusID = url.pathComponents[3] + let threadViewModel = RemoteThreadViewModel(context: provider.context, authContext: provider.authContext, statusID: statusID) + _ = await provider.coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) + } else { + _ = await provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) + } + } +} diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift index e868f418f..279cb562e 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift @@ -516,6 +516,61 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider & Aut } +// MARK: - card +extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { + + func tableViewCell( + _ cell: UITableViewCell, + notificationView: NotificationView, + statusView: StatusView, + didTapCardWithURL url: URL + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + + await DataSourceFacade.responseToURLAction( + provider: self, + status: status, + url: url + ) + } + } + + func tableViewCell( + _ cell: UITableViewCell, + notificationView: NotificationView, + quoteStatusView: StatusView, + didTapCardWithURL url: URL + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + + await DataSourceFacade.responseToURLAction( + provider: self, + status: status, + url: url + ) + } + } + +} + // MARK: a11y extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void) { diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index c157b7086..721263f30 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -120,7 +120,36 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte ) } } - + +} + +// MARK: - card +extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { + + func tableViewCell( + _ cell: UITableViewCell, + statusView: StatusView, + didTapCardWithURL url: URL + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + + await DataSourceFacade.responseToURLAction( + provider: self, + status: status, + url: url + ) + } + } + } // MARK: - media diff --git a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift index 7a603d5f0..45ad59334 100644 --- a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift +++ b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift @@ -28,11 +28,13 @@ protocol NotificationTableViewCellDelegate: AnyObject, AutoGenerateProtocolDeleg func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, acceptFollowRequestButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void) @@ -63,6 +65,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, metaText: metaText, didSelectMeta: meta) } + func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) { + delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, didTapCardWithURL: url) + } + func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) { delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, spoilerOverlayViewDidPressed: overlayView) } @@ -83,6 +89,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, metaText: metaText, didSelectMeta: meta) } + func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) { + delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, didTapCardWithURL: url) + } + func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) { delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, spoilerOverlayViewDidPressed: overlayView) } diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift index 034985c03..e76ba5006 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift @@ -27,6 +27,7 @@ protocol StatusTableViewCellDelegate: AnyObject, AutoGenerateProtocolDelegate { func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, contentSensitiveeToggleButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, didTapCardWithURL url: URL) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, pollTableView tableView: UITableView, didSelectRowAt indexPath: IndexPath) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, pollVoteButtonPressed button: UIButton) @@ -61,6 +62,10 @@ extension StatusViewDelegate where Self: StatusViewContainerTableViewCell { delegate?.tableViewCell(self, statusView: statusView, metaText: metaText, didSelectMeta: meta) } + func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) { + delegate?.tableViewCell(self, statusView: statusView, didTapCardWithURL: url) + } + func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) { delegate?.tableViewCell(self, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index 4cb2dca6d..fc5d8b247 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -16,6 +16,7 @@ public final class LinkPreviewButton: UIControl { private let containerStackView = UIStackView() private let labelStackView = UIStackView() + private let highlightView = UIView() private let imageView = UIImageView() private let titleLabel = UILabel() private let linkLabel = UILabel() @@ -30,6 +31,12 @@ public final class LinkPreviewButton: UIControl { imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40), ] + public override var isHighlighted: Bool { + didSet { + highlightView.isHidden = !isHighlighted + } + } + public override init(frame: CGRect) { super.init(frame: frame) @@ -38,6 +45,9 @@ public final class LinkPreviewButton: UIControl { layer.cornerRadius = 10 layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor + highlightView.backgroundColor = UIColor.black.withAlphaComponent(0.1) + highlightView.isHidden = true + titleLabel.numberOfLines = 2 titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) titleLabel.text = "This is where I'd put a title... if I had one" @@ -61,17 +71,23 @@ public final class LinkPreviewButton: UIControl { containerStackView.addArrangedSubview(imageView) containerStackView.addArrangedSubview(labelStackView) - containerStackView.distribution = .fill addSubview(containerStackView) + addSubview(highlightView) + containerStackView.isUserInteractionEnabled = false containerStackView.translatesAutoresizingMaskIntoConstraints = false + highlightView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ containerStackView.topAnchor.constraint(equalTo: topAnchor), containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor), containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor), containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor), + highlightView.topAnchor.constraint(equalTo: topAnchor), + highlightView.bottomAnchor.constraint(equalTo: bottomAnchor), + highlightView.leadingAnchor.constraint(equalTo: leadingAnchor), + highlightView.trailingAnchor.constraint(equalTo: trailingAnchor), ]) } @@ -100,10 +116,12 @@ public final class LinkPreviewButton: UIControl { if isCompact { containerStackView.alignment = .center containerStackView.axis = .horizontal + containerStackView.distribution = .fill NSLayoutConstraint.activate(compactImageConstraints) } else { containerStackView.alignment = .fill containerStackView.axis = .vertical + containerStackView.distribution = .equalSpacing NSLayoutConstraint.activate(largeImageConstraints) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index ddc1add5c..eb077d6db 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -22,6 +22,7 @@ public protocol NotificationViewDelegate: AnyObject { func notificationView(_ notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton) func notificationView(_ notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func notificationView(_ notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) @@ -29,6 +30,7 @@ public protocol NotificationViewDelegate: AnyObject { func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) @@ -496,7 +498,17 @@ extension NotificationView { // MARK: - StatusViewDelegate extension NotificationView: StatusViewDelegate { - + public func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) { + switch statusView { + case self.statusView: + delegate?.notificationView(self, statusView: statusView, didTapCardWithURL: url) + case quoteStatusView: + delegate?.notificationView(self, quoteStatusView: statusView, didTapCardWithURL: url) + default: + assertionFailure() + } + } + public func statusView(_ statusView: StatusView, headerDidPressed header: UIView) { // do nothing } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 3e90e03d4..a2621badd 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -23,6 +23,7 @@ public protocol StatusViewDelegate: AnyObject { func statusView(_ statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func statusView(_ statusView: StatusView, contentSensitiveeToggleButtonDidPressed button: UIButton) func statusView(_ statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) + func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func statusView(_ statusView: StatusView, pollTableView tableView: UITableView, didSelectRowAt indexPath: IndexPath) func statusView(_ statusView: StatusView, pollVoteButtonPressed button: UIButton) @@ -263,7 +264,13 @@ extension StatusView { // media mediaGridContainerView.delegate = self - + + linkPreviewButton.addTarget( + self, + action: #selector(linkPreviewButtonPressed), + for: .touchUpInside + ) + // poll pollTableView.translatesAutoresizingMaskIntoConstraints = false pollTableViewHeightLayoutConstraint = pollTableView.heightAnchor.constraint(equalToConstant: 44.0).priority(.required - 1) @@ -298,6 +305,12 @@ extension StatusView { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") delegate?.statusView(self, spoilerOverlayViewDidPressed: spoilerOverlayView) } + + @objc private func linkPreviewButtonPressed(_ sender: LinkPreviewButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + guard let url = viewModel.card?.url else { return } + delegate?.statusView(self, didTapCardWithURL: url) + } } From c8c05afac18cd0a7b7707989484de84fa2c23be3 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Thu, 24 Nov 2022 07:50:10 -0800 Subject: [PATCH 200/733] Revert package upgrades --- .../xcshareddata/swiftpm/Package.resolved | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 26b58956b..409b8820d 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Alamofire/Alamofire.git", "state" : { - "revision" : "78424be314842833c04bc3bef5b72e85fff99204", - "version" : "5.6.4" + "revision" : "354dda32d89fc8cd4f5c46487f64957d355f53d8", + "version" : "5.6.1" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Flipboard/FLAnimatedImage.git", "state" : { - "revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f", - "version" : "1.0.17" + "revision" : "e7f9fd4681ae41bf6f3056db08af4f401d61da52", + "version" : "1.0.16" } }, { @@ -104,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/kean/Nuke.git", "state" : { - "revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97", - "version" : "10.11.2" + "revision" : "0ea7545b5c918285aacc044dc75048625c8257cc", + "version" : "10.8.0" } }, { @@ -122,8 +122,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/uias/Pageboy", "state" : { - "revision" : "af8fa81788b893205e1ff42ddd88c5b0b315d7c5", - "version" : "3.7.0" + "revision" : "34ecb6e7c4e0e07494960ab2f7cc9a02293915a6", + "version" : "3.6.2" } }, { @@ -140,8 +140,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SDWebImage/SDWebImage.git", "state" : { - "revision" : "3312bf5e67b52fbce7c3caf431b0cda721a9f7bb", - "version" : "5.14.2" + "revision" : "2e63d0061da449ad0ed130768d05dceb1496de44", + "version" : "5.12.5" } }, { @@ -185,8 +185,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/scinfu/SwiftSoup.git", "state" : { - "revision" : "6778575285177365cbad3e5b8a72f2a20583cfec", - "version" : "2.4.3" + "revision" : "41e7c263fb8c277e980ebcb9b0b5f6031d3d4886", + "version" : "2.4.2" } }, { From 5e36bea7d5bad0598a6d8c9125d24c7ebd58441c Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Thu, 24 Nov 2022 08:56:49 -0800 Subject: [PATCH 201/733] Check in project changes --- Mastodon.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0c43b71df..453027074 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; }; 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; + 27D701F5292FC2D60031BCBB /* DataSourceFacade+URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D701F4292FC2D60031BCBB /* DataSourceFacade+URL.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; }; 2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; }; @@ -520,6 +521,7 @@ 0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; }; 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; + 27D701F4292FC2D60031BCBB /* DataSourceFacade+URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+URL.swift"; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SFSymbols.swift"; sourceTree = ""; }; 2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; }; @@ -2089,6 +2091,7 @@ DB63F778279ABF9C00455B82 /* DataSourceFacade+Reblog.swift */, DB63F77A279ACAE500455B82 /* DataSourceFacade+Favorite.swift */, DB0FCB67279507EF006C02E2 /* DataSourceFacade+Meta.swift */, + 27D701F4292FC2D60031BCBB /* DataSourceFacade+URL.swift */, DB0FCB79279576A2006C02E2 /* DataSourceFacade+Thread.swift */, DB63F74627990B0600455B82 /* DataSourceFacade+Hashtag.swift */, DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */, @@ -3142,6 +3145,7 @@ DB03A793272A7E5700EE37C5 /* SidebarListHeaderView.swift in Sources */, DB4FFC2B269EC39600D62E92 /* SearchToSearchDetailViewControllerAnimatedTransitioning.swift in Sources */, DB5B7298273112C800081888 /* FollowingListViewModel.swift in Sources */, + 27D701F5292FC2D60031BCBB /* DataSourceFacade+URL.swift in Sources */, 0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */, DB5B54AE2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift in Sources */, DB482A3F261331E8008AE74C /* UserTimelineViewModel+State.swift in Sources */, From 2bf9a541ed23b6cce5b164cb679b7e6aa9e8e302 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 20:23:30 +0100 Subject: [PATCH 202/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index a243dc9c4..4087a963e 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -654,7 +654,7 @@ "step1": "Cam 1 o 2", "step2": "Cam 2 o 2", "content1": "Hoffech chi ychwanegu unrhyw postiadau eraill i'r adroddiad?", - "content2": "Is there anything the moderators should know about this report?", + "content2": "Oes unrhyw beth y dylai'r cymedrolwyr wybod yn yr adroddiad hwn?", "report_sent_title": "Diolch am adrodd, byddwn yn ymchwilio i hyn.", "send": "Anfon adroddiad", "skip_to_send": "Anfon heb sylw", @@ -692,7 +692,7 @@ }, "step_final": { "dont_want_to_see_this": "Ddim eisiau gweld hwn?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Pan welwch chi gynnwys nad ydych chi'n ei hoffi ar Mastodon, gallwch dynnu'r person o'ch profiad.", "unfollow": "Dad-ddilyn", "unfollowed": "Dad-ddilynwyd", "unfollow_user": "Dad-ddilyn %s", From 433c4ab3ce5104d5473fa5317fc84467d4895a17 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 21:18:48 +0100 Subject: [PATCH 203/733] New translations Localizable.stringsdict (Welsh) --- .../StringsConvertor/input/cy.lproj/Localizable.stringsdict | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict index 5e374e92d..33bcd5a8d 100644 --- a/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict @@ -29,7 +29,7 @@ a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Mae'r terfyn mewnbwn yn fwy na %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -53,7 +53,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Mae'r terfyn mewnbwn yn %#@character_count@ character_count NSStringFormatSpecTypeKey From 680df84e949bf87f09a5b25dacc71052449ae8df Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Nov 2022 21:18:49 +0100 Subject: [PATCH 204/733] New translations ios-infoPlist.json (Welsh) --- .../StringsConvertor/input/cy.lproj/ios-infoPlist.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json index ee0c5bfee..e2a58387a 100644 --- a/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NSCameraUsageDescription": "Defnyddir hwn i gymryd llun am bost", + "NSPhotoLibraryAddUsageDescription": "Defnyddir hwn i gadw llun yn eich Photo Library", "NewPostShortcutItemTitle": "Post Newydd", "SearchShortcutItemTitle": "Chwilio" } From 02c38317c720e1916e1b1ab36e3f4794ad87a7a6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 25 Nov 2022 14:20:34 +0100 Subject: [PATCH 205/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index f74c75545..3fe636d1f 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -164,7 +164,7 @@ "emoji": "Emoji" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", + "unlisted": "Postingan ini dapat dilihat semua orang tetapi tidak ditampilkan di timeline publik.", "private": "Hanya pengikut mereka yang dapat melihat postingan ini.", "private_from_me": "Hanya pengikut saya yang dapat melihat postingan ini.", "direct": "Hanya pengguna yang disebut yang dapat melihat postingan ini." @@ -306,13 +306,13 @@ "blocked": "%s mengandung penyedia surel yang dilarang", "unreachable": "%s sepertinya tidak ada", "taken": "%s sudah digunakan", - "reserved": "%s is a reserved keyword", + "reserved": "%s adalah kata kunci yang dipesan", "accepted": "%s harus diterima", "blank": "%s diperlukan", "invalid": "%s tidak valid", "too_long": "%s terlalu panjang", "too_short": "%s terlalu pendek", - "inclusion": "%s is not a supported value" + "inclusion": "%s bukan nilai yang didukung" }, "special": { "username_invalid": "Nama pengguna hanya berisi angka karakter dan garis bawah", @@ -325,7 +325,7 @@ "server_rules": { "title": "Beberapa aturan dasar.", "subtitle": "Peraturan ini ditetapkan oleh admin %s.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "prompt": "Dengan melanjutkan, Anda tunduk pada ketentuan layanan dan kebijakan privasi untuk %s.", "terms_of_service": "kebijakan layanan", "privacy_policy": "kebijakan privasi", "button": { @@ -335,7 +335,7 @@ "confirm_email": { "title": "Satu hal lagi.", "subtitle": "Kami baru saja mengirim sebuah surel ke %s,\nketuk tautannya untuk mengkonfirmasi akun Anda.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Ketuk tautan yang kami kirimkan kepada Anda via email untuk memverifikasi akun Anda", "button": { "open_email_app": "Buka Aplikasi Surel", "resend": "Kirim ulang" @@ -361,7 +361,7 @@ "Publishing": "Mempublikasikan postingan...", "accessibility": { "logo_label": "Tombol Logo", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_hint": "Ketuk untuk menggulir ke atas dan ketuk lagi ke lokasi sebelumnya" } } }, @@ -392,8 +392,8 @@ "upload_failed": "Gagal Mengunggah", "can_not_recognize_this_media_attachment": "Tidak dapat mengenali lampiran media ini", "attachment_too_large": "Lampiran terlalu besar", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "compressing_state": "Mengompres...", + "server_processing_state": "Server Memproses..." }, "poll": { "duration_time": "Durasi: %s", @@ -403,9 +403,9 @@ "one_day": "1 Hari", "three_days": "3 Hari", "seven_days": "7 Hari", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "option_number": "Opsi %ld", + "the_poll_is_invalid": "Japat tidak valid", + "the_poll_has_empty_option": "Japat memiliki opsi kosong" }, "content_warning": { "placeholder": "Tulis peringatan yang akurat di sini..." @@ -417,7 +417,7 @@ "direct": "Hanya orang yang saya sebut" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Tekan spasi untuk menambahkan" }, "accessibility": { "append_attachment": "Tambahkan Lampiran", From 83fdaea2a2f54369d7ca70981b17a5725fa7b359 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 25 Nov 2022 15:43:13 +0100 Subject: [PATCH 206/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 3fe636d1f..ecafedfbd 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -423,12 +423,12 @@ "append_attachment": "Tambahkan Lampiran", "append_poll": "Tambahkan Japat", "remove_poll": "Hapus Japat", - "custom_emoji_picker": "Custom Emoji Picker", + "custom_emoji_picker": "Pemilih Emoji Kustom", "enable_content_warning": "Aktifkan Peringatan Konten", "disable_content_warning": "Nonaktifkan Peringatan Konten", - "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_visibility_menu": "Menu Visibilitas Postingan", + "post_options": "Opsi Postingan", + "posting_as": "Posting sebagai %s" }, "keyboard": { "discard_post": "Hapus Postingan", From b028380e7b9dfc848e8c79db834808979f7ece78 Mon Sep 17 00:00:00 2001 From: CMK Date: Sat, 26 Nov 2022 05:21:27 +0800 Subject: [PATCH 207/733] fix: scroll to top animation cannot trigger smooth issue --- Mastodon/Scene/Profile/ProfileViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 1184fb3d7..ffe8bcc83 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -885,7 +885,7 @@ extension ProfileViewController: MastodonMenuDelegate { // MARK: - ScrollViewContainer extension ProfileViewController: ScrollViewContainer { var scrollView: UIScrollView { - return tabBarPagerController.containerScrollView + return tabBarPagerController.relayScrollView } } From 2c78e1ec50018949a01a11c3b129515c9018549c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 00:57:44 +0100 Subject: [PATCH 208/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index ecafedfbd..87d31b70d 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -526,9 +526,9 @@ "recommend": { "button_text": "Lihat Semua", "hash_tag": { - "title": "Trending on Mastodon", + "title": "Sedang Tren di Mastodon", "description": "Hashtags that are getting quite a bit of attention", - "people_talking": "%s people are talking" + "people_talking": "%s orang sedang membicarakan" }, "accounts": { "title": "Akun-akun yang mungkin Anda sukai", @@ -624,8 +624,8 @@ "preference": { "title": "Preferensi", "true_black_dark_mode": "True black dark mode", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", + "disable_avatar_animation": "Nonaktifkan animasi avatar", + "disable_emoji_animation": "Nonaktifkan animasi emoji", "using_default_browser": "Use default browser to open links", "open_links_in_mastodon": "Buka tautan di Mastodon" }, @@ -655,7 +655,7 @@ "step2": "Langkah 2 dari 2", "content1": "Apakah ada postingan lain yang ingin Anda tambahkan ke laporannya?", "content2": "Ada yang moderator harus tahu tentang laporan ini?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", + "report_sent_title": "Terima kasih atas pelaporan Anda, kami akan memeriksa ini lebih lanjut.", "send": "Kirim Laporan", "skip_to_send": "Kirim tanpa komentar", "text_placeholder": "Ketik atau tempel komentar tambahan", @@ -664,13 +664,13 @@ "step_1_of_4": "Langkah 1 dari 4", "whats_wrong_with_this_post": "Ada yang salah dengan postingan ini?", "whats_wrong_with_this_account": "Ada yang salah dengan akun ini?", - "whats_wrong_with_this_username": "What's wrong with %s?", + "whats_wrong_with_this_username": "Ada yang salah dengan %s?", "select_the_best_match": "Pilih yang paling cocok", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", + "i_dont_like_it": "Saya tidak suka", + "it_is_not_something_you_want_to_see": "Ini bukan sesuatu yang Anda ingin lihat", + "its_spam": "Ini sampah", + "malicious_links_fake_engagement_or_repetetive_replies": "Tautan berbahaya, engagement palsu, atau balasan berulang", + "it_violates_server_rules": "Melanggar ketentuan server", "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", "its_something_else": "It’s something else", "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" From 849830d085e110154d2b4d92c3b00eb16fa621d1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 00:57:45 +0100 Subject: [PATCH 209/733] New translations Localizable.stringsdict (Indonesian) --- .../input/id.lproj/Localizable.stringsdict | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict index 5f80eb15a..3a39c085f 100644 --- a/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict @@ -19,7 +19,7 @@ a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Batas input melebihi %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -33,7 +33,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Batas input masih tersisa %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -78,7 +78,7 @@ NSStringFormatValueTypeKey ld other - Followed by %1$@, and %ld mutuals + Diikuti oleh %1$@, dan %ld mutual plural.count.metric_formatted.post @@ -148,7 +148,7 @@ NSStringFormatValueTypeKey ld other - %ld reblogs + Posting ulang %ld plural.count.reply From f9a83855a75efa80d568984d9b0302ce8dda9476 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 01:53:48 +0100 Subject: [PATCH 210/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 87d31b70d..c2dd3c215 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -671,57 +671,57 @@ "its_spam": "Ini sampah", "malicious_links_fake_engagement_or_repetetive_replies": "Tautan berbahaya, engagement palsu, atau balasan berulang", "it_violates_server_rules": "Melanggar ketentuan server", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", + "you_are_aware_that_it_breaks_specific_rules": "Anda yakin bahwa ini melanggar ketentuan khusus", + "its_something_else": "Alasan lainnya", "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", + "step_2_of_4": "Langkah 2 dari 4", + "which_rules_are_being_violated": "Ketentuan manakah yang dilanggar?", + "select_all_that_apply": "Pilih semua yang berlaku", "i_just_don’t_like_it": "I just don’t like it" }, "step_three": { - "step_3_of_4": "Step 3 of 4", + "step_3_of_4": "Langkah 3 dari 4", "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "select_all_that_apply": "Pilih semua yang berlaku" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "Langkah 4 dari 4", + "is_there_anything_else_we_should_know": "Ada hal lain yang perlu kami ketahui?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", + "dont_want_to_see_this": "Tidak ingin melihat ini?", "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", + "unfollow": "Berhenti ikuti", "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", + "unfollow_user": "Berhenti ikuti %s", + "mute_user": "Senyapkan %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", + "block_user": "Blokir %s", "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Tutup Pratinjau", + "show_next": "Tampilkan Berikutnya", + "show_previous": "Tampilkan Sebelumnya" } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", + "tab_bar_hint": "Profil yang dipilih saat ini: %s. Ketuk dua kali kemudian tahan untuk tampilkan ikon beralih akun", "dismiss_account_switcher": "Dismiss Account Switcher", - "add_account": "Add Account" + "add_account": "Tambah Akun" }, "wizard": { - "new_in_mastodon": "New in Mastodon", + "new_in_mastodon": "Baru di Mastodon", "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", "accessibility_hint": "Double tap to dismiss this wizard" }, "bookmark": { - "title": "Bookmarks" + "title": "Tandai" } } } From 3a732b688c2bde83f0c1d4b09503e5c01153d905 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Fri, 25 Nov 2022 20:16:42 -0800 Subject: [PATCH 211/733] Better layout --- .../View/Content/LinkPreviewButton.swift | 87 ++++++++++++------- .../View/Content/StatusView+ViewModel.swift | 1 + .../MastodonUI/View/Content/StatusView.swift | 4 +- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index fc5d8b247..22c9dc858 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -6,29 +6,38 @@ // import AlamofireImage -import LinkPresentation +import Combine import MastodonAsset import MastodonCore import CoreDataStack import UIKit public final class LinkPreviewButton: UIControl { - private let containerStackView = UIStackView() - private let labelStackView = UIStackView() + private var disposeBag = Set() + private let labelContainer = UIView() private let highlightView = UIView() private let imageView = UIImageView() private let titleLabel = UILabel() private let linkLabel = UILabel() private lazy var compactImageConstraints = [ + labelContainer.topAnchor.constraint(greaterThanOrEqualTo: topAnchor), + labelContainer.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor), + labelContainer.centerYAnchor.constraint(equalTo: centerYAnchor), + labelContainer.leadingAnchor.constraint(equalTo: imageView.trailingAnchor), imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), imageView.heightAnchor.constraint(equalTo: heightAnchor), - containerStackView.heightAnchor.constraint(equalToConstant: 85), + heightAnchor.constraint(equalToConstant: 85), ] private lazy var largeImageConstraints = [ + labelContainer.topAnchor.constraint(equalTo: imageView.bottomAnchor), + labelContainer.bottomAnchor.constraint(equalTo: bottomAnchor), + labelContainer.leadingAnchor.constraint(equalTo: leadingAnchor), imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40), + imageView.trailingAnchor.constraint(equalTo: trailingAnchor), + imageView.widthAnchor.constraint(equalTo: widthAnchor), ] public override var isHighlighted: Bool { @@ -40,50 +49,62 @@ public final class LinkPreviewButton: UIControl { public override init(frame: CGRect) { super.init(frame: frame) + apply(theme: ThemeService.shared.currentTheme.value) + + ThemeService.shared.currentTheme.sink { [weak self] theme in + self?.apply(theme: theme) + }.store(in: &disposeBag) + clipsToBounds = true layer.cornerCurve = .continuous layer.cornerRadius = 10 - layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor highlightView.backgroundColor = UIColor.black.withAlphaComponent(0.1) highlightView.isHidden = true titleLabel.numberOfLines = 2 - titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) - titleLabel.text = "This is where I'd put a title... if I had one" titleLabel.textColor = Asset.Colors.Label.primary.color + titleLabel.font = .preferredFont(forTextStyle: .body) - linkLabel.text = "Subtitle" linkLabel.numberOfLines = 1 - linkLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal) linkLabel.textColor = Asset.Colors.Label.secondary.color + linkLabel.font = .preferredFont(forTextStyle: .subheadline) imageView.tintColor = Asset.Colors.Label.secondary.color - imageView.backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true - labelStackView.addArrangedSubview(linkLabel) - labelStackView.addArrangedSubview(titleLabel) - labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10) - labelStackView.isLayoutMarginsRelativeArrangement = true - labelStackView.axis = .vertical + labelContainer.addSubview(titleLabel) + labelContainer.addSubview(linkLabel) + labelContainer.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10) - containerStackView.addArrangedSubview(imageView) - containerStackView.addArrangedSubview(labelStackView) - - addSubview(containerStackView) + addSubview(imageView) + addSubview(labelContainer) addSubview(highlightView) - containerStackView.isUserInteractionEnabled = false - containerStackView.translatesAutoresizingMaskIntoConstraints = false + subviews.forEach { $0.isUserInteractionEnabled = false } + + labelContainer.translatesAutoresizingMaskIntoConstraints = false + titleLabel.translatesAutoresizingMaskIntoConstraints = false + linkLabel.translatesAutoresizingMaskIntoConstraints = false + imageView.translatesAutoresizingMaskIntoConstraints = false highlightView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - containerStackView.topAnchor.constraint(equalTo: topAnchor), - containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor), - containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor), - containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor), + titleLabel.topAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.topAnchor), + titleLabel.leadingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.leadingAnchor), + titleLabel.trailingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.trailingAnchor), + + linkLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 2), + linkLabel.bottomAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.bottomAnchor), + linkLabel.leadingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.leadingAnchor), + linkLabel.trailingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.trailingAnchor), + + labelContainer.trailingAnchor.constraint(equalTo: trailingAnchor), + + imageView.topAnchor.constraint(equalTo: topAnchor), + imageView.leadingAnchor.constraint(equalTo: leadingAnchor), + highlightView.topAnchor.constraint(equalTo: topAnchor), highlightView.bottomAnchor.constraint(equalTo: bottomAnchor), highlightView.leadingAnchor.constraint(equalTo: leadingAnchor), @@ -114,16 +135,13 @@ public final class LinkPreviewButton: UIControl { NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints) if isCompact { - containerStackView.alignment = .center - containerStackView.axis = .horizontal - containerStackView.distribution = .fill NSLayoutConstraint.activate(compactImageConstraints) } else { - containerStackView.alignment = .fill - containerStackView.axis = .vertical - containerStackView.distribution = .equalSpacing NSLayoutConstraint.activate(largeImageConstraints) } + + setNeedsLayout() + layoutIfNeeded() } public override func didMoveToWindow() { @@ -139,7 +157,12 @@ public final class LinkPreviewButton: UIControl { } private var photoIcon: UIImage? { - let configuration = UIImage.SymbolConfiguration(pointSize: 40) + let configuration = UIImage.SymbolConfiguration(pointSize: 32) return UIImage(systemName: "photo", withConfiguration: configuration) } + + private func apply(theme: Theme) { + layer.borderColor = theme.separator.cgColor + imageView.backgroundColor = theme.systemElevatedBackgroundColor + } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index e56d82aff..af6a1a680 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -316,6 +316,7 @@ extension StatusView.ViewModel { } statusView.contentMetaText.textView.alpha = isContentReveal ? 1 : 0 // keep the frame size and only display when revealing + statusView.linkPreviewButton.alpha = isContentReveal ? 1 : 0 statusView.setSpoilerOverlayViewHidden(isHidden: isContentReveal) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index a2621badd..642ac3007 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -388,7 +388,7 @@ extension StatusView.Style { // content container: V - [ contentMetaText ] statusView.contentContainer.axis = .vertical - statusView.contentContainer.spacing = 12 + statusView.contentContainer.spacing = 10 statusView.contentContainer.distribution = .fill statusView.contentContainer.alignment = .fill @@ -400,9 +400,7 @@ extension StatusView.Style { // status content statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView) - statusView.containerStackView.setCustomSpacing(16, after: statusView.contentMetaText.textView) statusView.contentContainer.addArrangedSubview(statusView.linkPreviewButton) - statusView.containerStackView.setCustomSpacing(16, after: statusView.linkPreviewButton) statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false statusView.containerStackView.addSubview(statusView.spoilerOverlayView) From 00af336298c63cbade770a38f412f1b1d56294ad Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Fri, 25 Nov 2022 20:20:26 -0800 Subject: [PATCH 212/733] Remove some debugging --- .../View/Content/StatusView+Configuration.swift | 8 -------- 1 file changed, 8 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index fb28d564d..96165cef6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -40,14 +40,6 @@ extension StatusView { extension StatusView { public func configure(status: Status) { - if let card = status.card { - print("---- \(card.title)") - print("---- \(card.url)") - print("---- \(card.image)") - print("---- \(card.width)") - print("---- \(card.height)") - } - viewModel.objects.insert(status) if let reblog = status.reblog { viewModel.objects.insert(reblog) From ac5e68b74bac97886ca5a3dcc40f8db0b180e0dd Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 24 Nov 2022 07:46:27 +0100 Subject: [PATCH 213/733] feat: Delete Users / Statuses on Mute --- Mastodon/Supporting Files/SceneDelegate.swift | 3 + .../CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData 5.xcdatamodel/contents | 254 ++++++++++++++++++ .../Service/API/APIService+Mute.swift | 30 +++ .../Service/InstanceService.swift | 17 ++ .../API/Mastodon+API+Account+Friendship.swift | 50 ++++ 6 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 4476477fd..15c4069cb 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -112,6 +112,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // trigger authenticated user account update AppContext.shared.authenticationService.updateActiveUserAccountPublisher.send() + + // update mutes and blocks and remove related data + AppContext.shared.instanceService.updateMutesAndBlocks() if let shortcutItem = savedShortCutItem { Task { diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index 1d5ea989f..2145ac780 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 4.xcdatamodel + CoreData 5.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents new file mode 100644 index 000000000..1388fa741 --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift index ee43ddce8..28be45309 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift @@ -21,6 +21,36 @@ extension APIService { let isMuting: Bool } + @discardableResult + public func getMutes( + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + let managedObjectContext = backgroundManagedObjectContext + + let response = try await Mastodon.API.Account.mutes( + session: session, + domain: authenticationBox.domain, + authorization: authenticationBox.userAuthorization + ).singleOutput() + + let userIDs = response.value.map { $0.id } + let predicate = NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), userIDs) + + let fetchRequest = MastodonUser.fetchRequest() + fetchRequest.predicate = predicate + fetchRequest.includesPropertyValues = false + + try await managedObjectContext.performChanges { + let accounts = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] + + for account in accounts { + managedObjectContext.delete(account) + } + } + + return response + } + public func toggleMute( user: ManagedObjectRecord, authenticationBox: MastodonAuthenticationBox diff --git a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift index 4cd804036..742476c28 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift @@ -101,3 +101,20 @@ extension InstanceService { .store(in: &disposeBag) } } + +public extension InstanceService { + func updateMutesAndBlocks() { + Task { + for authBox in authenticationService?.mastodonAuthenticationBoxes ?? [] { + do { + try await apiService?.getMutes( + authenticationBox: authBox + ) + self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Instance] update mutes and blocks succeeded") + } catch { + self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Instance] update mutes and blocks failure: \(error.localizedDescription)") + } + } + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift index 2c0c39b97..c461466e7 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift @@ -414,3 +414,53 @@ extension Mastodon.API.Account { } } + +extension Mastodon.API.Account { + + static func mutesEndpointURL( + domain: String + ) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("mutes") + } + + /// View all mutes + /// + /// View your mutes. See also accounts/:id/{mute,unmute}. + /// + /// - Since: 0.0.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/4/1 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/accounts/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - accountID: id for account + /// - authorization: User token. + /// - Returns: `AnyPublisher` contains `Relationship` nested in the response + public static func mutes( + session: URLSession, + domain: String, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: mutesEndpointURL(domain: domain), + query: MutesQuery(), + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.Account].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + + struct MutesQuery: GetQuery { + var queryItems: [URLQueryItem]? { + [URLQueryItem(name: "limit", value: "-1")] + } + } + } +} From 65ed6650e817b3c388da606a9ed6eb7db21b4cb7 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 24 Nov 2022 07:53:04 +0100 Subject: [PATCH 214/733] feat: Implement deletion of records for blocked users --- ...omeTimelineViewModel+LoadLatestState.swift | 2 + .../Service/API/APIService+Block.swift | 30 ++++++++++++ .../Service/InstanceService.swift | 5 ++ .../API/Mastodon+API+Account+Friendship.swift | 47 +++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index 8bf1421b1..d243c9a96 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -86,6 +86,8 @@ extension HomeTimelineViewModel.LoadLatestState { await enter(state: Idle.self) viewModel.homeTimelineNavigationBarTitleViewModel.receiveLoadingStateCompletion(.finished) + viewModel.context.instanceService.updateMutesAndBlocks() + // stop refresher if no new statuses let statuses = response.value let newStatuses = statuses.filter { !latestStatusIDs.contains($0.id) } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift index 7c78a65f7..d138d0401 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift @@ -22,6 +22,36 @@ extension APIService { let isFollowing: Bool } + @discardableResult + public func getBlocked( + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + let managedObjectContext = backgroundManagedObjectContext + + let response = try await Mastodon.API.Account.blocks( + session: session, + domain: authenticationBox.domain, + authorization: authenticationBox.userAuthorization + ).singleOutput() + + let userIDs = response.value.map { $0.id } + let predicate = NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), userIDs) + + let fetchRequest = MastodonUser.fetchRequest() + fetchRequest.predicate = predicate + fetchRequest.includesPropertyValues = false + + try await managedObjectContext.performChanges { + let accounts = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] + + for account in accounts { + managedObjectContext.delete(account) + } + } + + return response + } + public func toggleBlock( user: ManagedObjectRecord, authenticationBox: MastodonAuthenticationBox diff --git a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift index 742476c28..99ad6d0a2 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift @@ -110,6 +110,11 @@ public extension InstanceService { try await apiService?.getMutes( authenticationBox: authBox ) + + try await apiService?.getBlocked( + authenticationBox: authBox + ) + self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Instance] update mutes and blocks succeeded") } catch { self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Instance] update mutes and blocks failure: \(error.localizedDescription)") diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift index c461466e7..65045fbd0 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift @@ -215,6 +215,53 @@ extension Mastodon.API.Account { } +public extension Mastodon.API.Account { + + static func blocksEndpointURL(domain: String) -> URL { + return Mastodon.API.endpointURL(domain: domain).appendingPathComponent("blocks") + } + + /// Block + /// + /// Block the given account. Clients should filter statuses from this account if received (e.g. due to a boost in the Home timeline). + /// + /// - Since: 0.0.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/4/1 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/blocks/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - authorization: User token. + /// - Returns: `AnyPublisher` contains `Relationship` nested in the response + static func blocks( + session: URLSession, + domain: String, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: blocksEndpointURL(domain: domain), + query: BlocksQuery(), + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.Account].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + private struct BlocksQuery: GetQuery { + var queryItems: [URLQueryItem]? { + [URLQueryItem(name: "limit", value: "-1")] + } + } + +} + extension Mastodon.API.Account { static func blockEndpointURL(domain: String, accountID: Mastodon.Entity.Account.ID) -> URL { From 6be1e502b731a6473b15c49430d1b440db1a9673 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 24 Nov 2022 13:24:56 +0100 Subject: [PATCH 215/733] chore: Use MastodonUser.predicate in APIService+Mute --- .../Sources/MastodonCore/Service/API/APIService+Mute.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift index 28be45309..0e00c5e0b 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift @@ -34,7 +34,7 @@ extension APIService { ).singleOutput() let userIDs = response.value.map { $0.id } - let predicate = NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), userIDs) + let predicate = MastodonUser.predicate(domain: authenticationBox.domain, ids: userIDs) let fetchRequest = MastodonUser.fetchRequest() fetchRequest.predicate = predicate From 9c86dfe166d38bec18d4b260feb555a4bb1f8f81 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 24 Nov 2022 13:26:35 +0100 Subject: [PATCH 216/733] chore: Remove limit query for GET Block/Mute --- .../MastodonSDK/API/Mastodon+API+Account+Friendship.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift index 65045fbd0..2619891a7 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift @@ -256,7 +256,7 @@ public extension Mastodon.API.Account { private struct BlocksQuery: GetQuery { var queryItems: [URLQueryItem]? { - [URLQueryItem(name: "limit", value: "-1")] + nil } } @@ -506,7 +506,7 @@ extension Mastodon.API.Account { struct MutesQuery: GetQuery { var queryItems: [URLQueryItem]? { - [URLQueryItem(name: "limit", value: "-1")] + nil } } } From 12cb8cf8d6a9b2ec8632e90a52a11cb01f29fb3d Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 24 Nov 2022 14:21:53 +0100 Subject: [PATCH 217/733] feat: Implement blocks/mutes pagination using link header --- .../Service/API/APIService+Block.swift | 22 ++++++++-- .../Service/API/APIService+Mute.swift | 20 +++++++-- .../API/Mastodon+API+Account+Friendship.swift | 42 +++++++++++++++++-- .../Response/Mastodon+Response+Content.swift | 28 +++++++++++++ 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift index d138d0401..c53428fbb 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift @@ -25,18 +25,27 @@ extension APIService { @discardableResult public func getBlocked( authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + try await _getBlocked(sinceID: nil, limit: 40, authenticationBox: authenticationBox) + } + + private func _getBlocked( + sinceID: Mastodon.Entity.Status.ID?, + limit: Int, + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { let managedObjectContext = backgroundManagedObjectContext - let response = try await Mastodon.API.Account.blocks( session: session, domain: authenticationBox.domain, + sinceID: sinceID, + limit: limit, authorization: authenticationBox.userAuthorization ).singleOutput() let userIDs = response.value.map { $0.id } - let predicate = NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), userIDs) - + let predicate = MastodonUser.predicate(domain: authenticationBox.domain, ids: userIDs) + let fetchRequest = MastodonUser.fetchRequest() fetchRequest.predicate = predicate fetchRequest.includesPropertyValues = false @@ -49,7 +58,12 @@ extension APIService { } } - return response + /// only try to paginate if retrieved userIDs count is larger than the set limit and if we get a prev linkId that's different than the currently used one + guard userIDs.count == limit, let prevSinceId = response.link?.linkIDs[.linkPrev]?.sinceId, sinceID != prevSinceId else { + return response + } + + return try await _getBlocked(sinceID: prevSinceId, limit: limit, authenticationBox: authenticationBox) } public func toggleBlock( diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift index 0e00c5e0b..42178d573 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift @@ -24,18 +24,27 @@ extension APIService { @discardableResult public func getMutes( authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + try await _getMutes(sinceID: nil, limit: 40, authenticationBox: authenticationBox) + } + + private func _getMutes( + sinceID: Mastodon.Entity.Status.ID?, + limit: Int, + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { let managedObjectContext = backgroundManagedObjectContext - let response = try await Mastodon.API.Account.mutes( session: session, domain: authenticationBox.domain, + sinceID: sinceID, + limit: limit, authorization: authenticationBox.userAuthorization ).singleOutput() let userIDs = response.value.map { $0.id } let predicate = MastodonUser.predicate(domain: authenticationBox.domain, ids: userIDs) - + let fetchRequest = MastodonUser.fetchRequest() fetchRequest.predicate = predicate fetchRequest.includesPropertyValues = false @@ -48,7 +57,12 @@ extension APIService { } } - return response + /// only try to paginate if retrieved userIDs count is larger than the set limit and if we get a prev linkId that's different than the currently used one + guard userIDs.count == limit, let prevSinceId = response.link?.linkIDs[.linkPrev]?.sinceId, sinceID != prevSinceId else { + return response + } + + return try await _getMutes(sinceID: prevSinceId, limit: limit, authenticationBox: authenticationBox) } public func toggleMute( diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift index 2619891a7..e191c3200 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+Friendship.swift @@ -239,11 +239,13 @@ public extension Mastodon.API.Account { static func blocks( session: URLSession, domain: String, + sinceID: Mastodon.Entity.Status.ID? = nil, + limit: Int, authorization: Mastodon.API.OAuth.Authorization ) -> AnyPublisher, Error> { let request = Mastodon.API.get( url: blocksEndpointURL(domain: domain), - query: BlocksQuery(), + query: BlocksQuery(sinceID: sinceID, limit: limit), authorization: authorization ) return session.dataTaskPublisher(for: request) @@ -255,8 +257,23 @@ public extension Mastodon.API.Account { } private struct BlocksQuery: GetQuery { + private let sinceID: Mastodon.Entity.Status.ID? + private let limit: Int? + + public init( + sinceID: Mastodon.Entity.Status.ID?, + limit: Int? + ) { + self.sinceID = sinceID + self.limit = limit + } + var queryItems: [URLQueryItem]? { - nil + var items: [URLQueryItem] = [] + sinceID.flatMap { items.append(URLQueryItem(name: "since_id", value: $0)) } + limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) } + guard !items.isEmpty else { return nil } + return items } } @@ -490,11 +507,13 @@ extension Mastodon.API.Account { public static func mutes( session: URLSession, domain: String, + sinceID: Mastodon.Entity.Status.ID? = nil, + limit: Int?, authorization: Mastodon.API.OAuth.Authorization ) -> AnyPublisher, Error> { let request = Mastodon.API.get( url: mutesEndpointURL(domain: domain), - query: MutesQuery(), + query: MutesQuery(sinceID: sinceID, limit: limit), authorization: authorization ) return session.dataTaskPublisher(for: request) @@ -505,8 +524,23 @@ extension Mastodon.API.Account { .eraseToAnyPublisher() struct MutesQuery: GetQuery { + private let sinceID: Mastodon.Entity.Status.ID? + private let limit: Int? + + public init( + sinceID: Mastodon.Entity.Status.ID?, + limit: Int? + ) { + self.sinceID = sinceID + self.limit = limit + } + var queryItems: [URLQueryItem]? { - nil + var items: [URLQueryItem] = [] + sinceID.flatMap { items.append(URLQueryItem(name: "since_id", value: $0)) } + limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) } + guard !items.isEmpty else { return nil } + return items } } } diff --git a/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift b/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift index 6cf95752b..aa156ac16 100644 --- a/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift +++ b/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift @@ -106,6 +106,7 @@ extension Mastodon.Response { public struct Link { public let maxID: Mastodon.Entity.Status.ID? public let minID: Mastodon.Entity.Status.ID? + public let linkIDs: [String: Mastodon.Entity.Status.ID] public let offset: Int? init(link: String) { @@ -135,6 +136,33 @@ extension Mastodon.Response { let offset = link[range] return Int(offset) }() + self.linkIDs = { + var linkIDs = [String: Mastodon.Entity.Status.ID]() + let links = link.components(separatedBy: ", ") + for link in links { + guard let regex = try? NSRegularExpression(pattern: "<(.*)>; *rel=\"(.*)\"") else { return [:] } + let results = regex.matches(in: link, options: [], range: NSRange(link.startIndex.. _XCCurrentVersionName - CoreData 5.xcdatamodel + CoreData 4.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents deleted file mode 100644 index 1388fa741..000000000 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift index 62d4b435c..60f15367e 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift @@ -51,10 +51,10 @@ extension APIService { fetchRequest.includesPropertyValues = false try await managedObjectContext.performChanges { - let accounts = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] + let users = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] - for account in accounts { - managedObjectContext.delete(account) + for user in users { + user.statuses.deleteAllFeedsForBlockOrMute(in: managedObjectContext) } } @@ -149,3 +149,11 @@ extension APIService { } } + +extension Set { + func deleteAllFeedsForBlockOrMute(in managedObjectContext: NSManagedObjectContext) { + map { $0.feeds.union($0.reblogFrom.map { $0.feeds }.flatMap { $0 }) } + .flatMap { $0 } + .forEach(managedObjectContext.delete) + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift index 1d6738e32..e0e95fd35 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift @@ -50,10 +50,10 @@ extension APIService { fetchRequest.includesPropertyValues = false try await managedObjectContext.performChanges { - let accounts = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] + let users = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] - for account in accounts { - managedObjectContext.delete(account) + for user in users { + user.statuses.deleteAllFeedsForBlockOrMute(in: managedObjectContext) } } From 54a75d4138490a75dcef02d90c79af85a52e7130 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 14:43:36 +0100 Subject: [PATCH 221/733] feat: Delete Status and Notification Feeds for Blocked/Muted Users --- .../Service/API/APIService+Block.swift | 20 ++++++++++++++----- .../Service/API/APIService+Mute.swift | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift index 60f15367e..19c5ff437 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Block.swift @@ -54,7 +54,7 @@ extension APIService { let users = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] for user in users { - user.statuses.deleteAllFeedsForBlockOrMute(in: managedObjectContext) + user.deleteStatusAndNotificationFeeds(in: managedObjectContext) } } @@ -150,10 +150,20 @@ extension APIService { } -extension Set { - func deleteAllFeedsForBlockOrMute(in managedObjectContext: NSManagedObjectContext) { - map { $0.feeds.union($0.reblogFrom.map { $0.feeds }.flatMap { $0 }) } +extension MastodonUser { + func deleteStatusAndNotificationFeeds(in context: NSManagedObjectContext) { + statuses.map { + $0.feeds + .union($0.reblogFrom.map { $0.feeds }.flatMap { $0 }) + .union($0.notifications.map { $0.feeds }.flatMap { $0 }) + } .flatMap { $0 } - .forEach(managedObjectContext.delete) + .forEach(context.delete) + + notifications.map { + $0.feeds + } + .flatMap { $0 } + .forEach(context.delete) } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift index e0e95fd35..cc46872f4 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Mute.swift @@ -53,7 +53,7 @@ extension APIService { let users = try managedObjectContext.fetch(fetchRequest) as! [MastodonUser] for user in users { - user.statuses.deleteAllFeedsForBlockOrMute(in: managedObjectContext) + user.deleteStatusAndNotificationFeeds(in: managedObjectContext) } } From 5608cad673147c68865307483b5b3fa8cd43fe3d Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Sat, 26 Nov 2022 16:26:06 +0100 Subject: [PATCH 222/733] Fix after merge. --- ...ostToMediaPreviewViewControllerAnimatedTransitioning.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index 7abe99848..a436fa1b3 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -253,10 +253,6 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { return rect }() let maskLayerToPath = maskLayerToRect.flatMap { UIBezierPath(rect: $0) }?.cgPath - - - // FIXME: - _ = maskLayerToFinalRect.flatMap { UIBezierPath(rect: $0) }?.cgPath if let maskLayerToPath = maskLayerToPath { maskLayer.path = maskLayerToPath From a247bfc91f7618600151fc339b07cf1d24ccaae3 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Sat, 26 Nov 2022 16:38:02 +0100 Subject: [PATCH 223/733] Remove dead code. --- .../Publisher/MastodonStatusPublisher.swift | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusPublisher.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusPublisher.swift index 93f3dd3a1..3cecbc675 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusPublisher.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusPublisher.swift @@ -108,11 +108,6 @@ extension MastodonStatusPublisher: StatusPublisher { // Task: attachment - let uploadContext = AttachmentViewModel.UploadContext( - apiService: api, - authContext: authContext - ) - var attachmentIDs: [Mastodon.Entity.Attachment.ID] = [] for attachmentViewModel in attachmentViewModels { // set progress @@ -161,11 +156,6 @@ extension MastodonStatusPublisher: StatusPublisher { guard pollOptions != nil else { return nil } return self.pollExpireConfigurationOption.seconds }() - let pollMultiple: Bool? = { - guard self.isPollComposing else { return nil } - guard pollOptions != nil else { return nil } - return self.pollMultipleConfigurationOption - }() let inReplyToID: Mastodon.Entity.Status.ID? = try await api.backgroundManagedObjectContext.perform { guard let replyTo = self.replyTo?.object(in: api.backgroundManagedObjectContext) else { return nil } return replyTo.id From 446ac651936cf6f58d02e9e434401378da5f008c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 17:21:22 +0100 Subject: [PATCH 224/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index b624b194d..5498a3b2b 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -2,46 +2,46 @@ "common": { "alerts": { "common": { - "please_try_again": "Si us plau intenta-ho de nou.", - "please_try_again_later": "Si us plau, prova-ho més tard." + "please_try_again": "Torna-ho a provar.", + "please_try_again_later": "Prova-ho més tard." }, "sign_up_failure": { "title": "Error en el registre" }, "server_error": { - "title": "Error del Servidor" + "title": "Error del servidor" }, "vote_failure": { - "title": "Error del Vot", + "title": "Error en votar", "poll_ended": "L'enquesta ha finalitzat" }, "discard_post_content": { "title": "Descarta l'esborrany", - "message": "Confirma per a descartar el contingut de la publicació composta." + "message": "Confirma per a descartar el contingut de la publicació." }, "publish_post_failure": { - "title": "Error de Publicació", - "message": "No s'ha pogut enviar la publicació.\nComprova la teva connexió a Internet.", + "title": "Error en publicar", + "message": "No s'ha pogut enviar la publicació.\nComprova la connexió a Internet.", "attachments_message": { "video_attach_with_photo": "No es pot adjuntar un vídeo a una publicació que ja contingui imatges.", - "more_than_one_video": "No pots adjuntar més d'un vídeo." + "more_than_one_video": "No es pot adjuntar més d'un vídeo." } }, "edit_profile_failure": { - "title": "Error al Editar el Perfil", - "message": "No es pot editar el perfil. Si us plau torna-ho a provar." + "title": "Error en editar el perfil", + "message": "No es pot editar el perfil. Torna-ho a provar." }, "sign_out": { - "title": "Tancar Sessió", - "message": "Estàs segur que vols tancar la sessió?", - "confirm": "Tancar Sessió" + "title": "Tanca la sessió", + "message": "Segur que vols tancar la sessió?", + "confirm": "Tanca la sessió" }, "block_domain": { - "title": "Estàs segur, realment segur que vols bloquejar totalment %s? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veureu contingut d’aquest domini i se suprimirà qualsevol dels vostres seguidors d’aquest domini.", - "block_entire_domain": "Bloquejar Domini" + "title": "Estàs totalment segur que vols bloquejar per complet %s? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veureu contingut d’aquest domini i se suprimirà qualsevol dels vostres seguidors d’aquest domini.", + "block_entire_domain": "Bloca el domini" }, "save_photo_failure": { - "title": "Error al Desar la Foto", + "title": "Error en desar la foto", "message": "Activa el permís d'accés a la biblioteca de fotos per desar-la." }, "delete_post": { @@ -79,7 +79,7 @@ "see_more": "Veure més", "preview": "Vista prèvia", "share": "Comparteix", - "share_user": "Compartir %s", + "share_user": "Comparteix %s", "share_post": "Compartir Publicació", "open_in_safari": "Obrir a Safari", "open_in_browser": "Obre al navegador", From 81f734750edb7f9c932e2f6c8c87d357afeae4ac Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 17:21:23 +0100 Subject: [PATCH 225/733] New translations Localizable.stringsdict (Catalan) --- .../input/ca.lproj/Localizable.stringsdict | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict index 947597417..615fd0c48 100644 --- a/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict @@ -408,7 +408,7 @@ NSStringFormatValueTypeKey ld one - fa 1 día + fa 1 dia other fa %ld dies @@ -424,7 +424,7 @@ NSStringFormatValueTypeKey ld one - fa 1h + fa 1 h other fa %ld hores @@ -440,9 +440,9 @@ NSStringFormatValueTypeKey ld one - fa 1 minut + fa 1 min other - fa %ld minuts + fa %ld min date.second.ago.abbr @@ -456,9 +456,9 @@ NSStringFormatValueTypeKey ld one - fa 1 segon + fa 1 s other - fa %ld segons + fa %ld s From 07424288dc2487a1575ee6ea64af09c1d22f3e6a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 17:21:24 +0100 Subject: [PATCH 226/733] New translations Intents.strings (Catalan) --- .../StringsConvertor/Intents/input/ca.lproj/Intents.strings | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings index 6b92eb263..c02ac08cf 100644 --- a/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings @@ -22,7 +22,7 @@ "ZbSjzC" = "Visibilitat"; -"Zo4jgJ" = "Visibilitat de la Publicació"; +"Zo4jgJ" = "Visibilitat de la publicació"; "apSxMG-dYQ5NN" = "Hi ha ${count} opcions que coincideixen amb ‘Públic’."; @@ -30,9 +30,9 @@ "ayoYEb-dYQ5NN" = "${content}, Públic"; -"ayoYEb-ehFLjY" = "${content}, Només Seguidors"; +"ayoYEb-ehFLjY" = "${content}, Només seguidors"; -"dUyuGg" = "Publicació"; +"dUyuGg" = "Publica a Mastodon"; "dYQ5NN" = "Públic"; From 3961f478dc44a9dca3aefae5b7f5e11d0f86b8c9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 18:16:37 +0100 Subject: [PATCH 227/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 5498a3b2b..42c11c9b5 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -42,11 +42,11 @@ }, "save_photo_failure": { "title": "Error en desar la foto", - "message": "Activa el permís d'accés a la biblioteca de fotos per desar-la." + "message": "Activa el permís d'accés a la biblioteca de fotos per a desar-la." }, "delete_post": { - "title": "Esborrar Publicació", - "message": "Estàs segur que vols suprimir aquesta publicació?" + "title": "Eliminar la publicació", + "message": "Segur que vols eliminar aquesta publicació?" }, "clean_cache": { "title": "Neteja la memòria cau", @@ -67,20 +67,20 @@ "done": "Fet", "confirm": "Confirma", "continue": "Continua", - "compose": "Composa", + "compose": "Redacta", "cancel": "Cancel·la", "discard": "Descarta", "try_again": "Torna a provar", "take_photo": "Fes una foto", "save_photo": "Desa la foto", "copy_photo": "Copia la foto", - "sign_in": "Iniciar sessió", + "sign_in": "Inicia sessió", "sign_up": "Crea un compte", - "see_more": "Veure més", + "see_more": "Mostra'n més", "preview": "Vista prèvia", "share": "Comparteix", "share_user": "Comparteix %s", - "share_post": "Compartir Publicació", + "share_post": "Comparteix la publicació", "open_in_safari": "Obrir a Safari", "open_in_browser": "Obre al navegador", "find_people": "Busca persones a seguir", @@ -110,9 +110,9 @@ "previous_status": "Publicació anterior", "next_status": "Publicació següent", "open_status": "Obre la publicació", - "open_author_profile": "Obre el Perfil de l'Autor", - "open_reblogger_profile": "Obre el Perfil del Impulsor", - "reply_status": "Respon a la Publicació", + "open_author_profile": "Obre el perfil de l'autor", + "open_reblogger_profile": "Obre el perfil de l'impuls", + "reply_status": "Respon a la publicació", "toggle_reblog": "Commuta l'Impuls de la Publicació", "toggle_favorite": "Commuta el Favorit de la Publicació", "toggle_content_warning": "Commuta l'Avís de Contingut", @@ -138,16 +138,16 @@ }, "meta_entity": { "url": "Enllaç: %s", - "hashtag": "Etiqueta %s", - "mention": "Mostra el Perfil: %s", + "hashtag": "Etiqueta: %s", + "mention": "Mostra el perfil: %s", "email": "Correu electrònic: %s" }, "actions": { "reply": "Respon", - "reblog": "Impuls", - "unreblog": "Desfer l'impuls", + "reblog": "Impulsa", + "unreblog": "Desfés l'impuls", "favorite": "Favorit", - "unfavorite": "Desfer Favorit", + "unfavorite": "Desfés el favorit", "menu": "Menú", "hide": "Amaga", "show_image": "Mostra la imatge", @@ -161,10 +161,10 @@ "link": "Enllaç", "hashtag": "Etiqueta", "email": "Correu electrònic", - "emoji": "Emoji" + "emoji": "Emojis" }, "visibility": { - "unlisted": "Tothom pot veure aquesta publicació però no es mostra en la línia de temps pública.", + "unlisted": "Tothom pot veure aquesta publicació, però no es mostra en la línia de temps pública.", "private": "Només els seus seguidors poden veure aquesta publicació.", "private_from_me": "Només els meus seguidors poden veure aquesta publicació.", "direct": "Només l'usuari mencionat pot veure aquesta publicació." @@ -173,7 +173,7 @@ "friendship": { "follow": "Segueix", "following": "Seguint", - "request": "Petició", + "request": "Sol·licitud", "pending": "Pendent", "block": "Bloca", "block_user": "Bloca %s", From 50eac9f0b25e2e79450850b921203d1c9ddd8c93 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Nov 2022 20:15:30 +0100 Subject: [PATCH 228/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 6eea8c3b2..7bcf5da60 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "หน้าแรก", "search": "ค้นหา", - "notifications": "Notifications", + "notifications": "การแจ้งเตือน", "profile": "โปรไฟล์" }, "keyboard": { From 0e5261ef9476d18794aceb3401cf45e775bfb597 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 16:08:52 -0800 Subject: [PATCH 229/733] Fix scroll to top --- .../Root/MainTab/MainTabBarController.swift | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 2e5d5ae58..a2778b551 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -569,25 +569,24 @@ extension MainTabBarController: UITabBarControllerDelegate { composeButtonDidPressed(tabBarController) return false } + + // Assert index is as same as the tab rawValue. This check needs to be done `shouldSelect` + // because the nav controller has already popped in `didSelect`. + if currentTab.rawValue == tabBarController.selectedIndex, + let navigationController = viewController as? UINavigationController, + navigationController.viewControllers.count == 1, + let scrollViewContainer = navigationController.topViewController as? ScrollViewContainer { + scrollViewContainer.scrollToTop(animated: true) + } + return true } func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: select %s", ((#file as NSString).lastPathComponent), #line, #function, viewController.debugDescription) - defer { - if let tab = Tab(rawValue: viewController.tabBarItem.tag) { - currentTab = tab - } + if let tab = Tab(rawValue: viewController.tabBarItem.tag) { + currentTab = tab } - // assert index is as same as the tab rawValue - guard currentTab.rawValue == tabBarController.selectedIndex, - let navigationController = viewController as? UINavigationController, - navigationController.viewControllers.count == 1, - let scrollViewContainer = navigationController.topViewController as? ScrollViewContainer else { - return - } - - scrollViewContainer.scrollToTop(animated: true) } } From 439217d0e1d4bc5962c578762579947f793d738e Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 19:21:47 -0800 Subject: [PATCH 230/733] Constraints work --- .../View/Content/LinkPreviewButton.swift | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift index 22c9dc858..db700cca1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift @@ -15,29 +15,25 @@ import UIKit public final class LinkPreviewButton: UIControl { private var disposeBag = Set() - private let labelContainer = UIView() + private let containerStackView = UIStackView() + private let labelStackView = UIStackView() + private let highlightView = UIView() private let imageView = UIImageView() private let titleLabel = UILabel() private let linkLabel = UILabel() private lazy var compactImageConstraints = [ - labelContainer.topAnchor.constraint(greaterThanOrEqualTo: topAnchor), - labelContainer.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor), - labelContainer.centerYAnchor.constraint(equalTo: centerYAnchor), - labelContainer.leadingAnchor.constraint(equalTo: imageView.trailingAnchor), - imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), imageView.heightAnchor.constraint(equalTo: heightAnchor), + imageView.widthAnchor.constraint(equalTo: heightAnchor), heightAnchor.constraint(equalToConstant: 85), ] private lazy var largeImageConstraints = [ - labelContainer.topAnchor.constraint(equalTo: imageView.bottomAnchor), - labelContainer.bottomAnchor.constraint(equalTo: bottomAnchor), - labelContainer.leadingAnchor.constraint(equalTo: leadingAnchor), - imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40), - imageView.trailingAnchor.constraint(equalTo: trailingAnchor), - imageView.widthAnchor.constraint(equalTo: widthAnchor), + imageView.heightAnchor.constraint( + equalTo: imageView.widthAnchor, + multiplier: 21 / 40 + ).priority(.defaultLow - 1), ] public override var isHighlighted: Bool { @@ -73,43 +69,29 @@ public final class LinkPreviewButton: UIControl { imageView.tintColor = Asset.Colors.Label.secondary.color imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true + imageView.setContentHuggingPriority(.zero, for: .horizontal) + imageView.setContentHuggingPriority(.zero, for: .vertical) + imageView.setContentCompressionResistancePriority(.zero, for: .horizontal) + imageView.setContentCompressionResistancePriority(.zero, for: .vertical) - labelContainer.addSubview(titleLabel) - labelContainer.addSubview(linkLabel) - labelContainer.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10) + labelStackView.addArrangedSubview(titleLabel) + labelStackView.addArrangedSubview(linkLabel) + labelStackView.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10) + labelStackView.isLayoutMarginsRelativeArrangement = true + labelStackView.axis = .vertical - addSubview(imageView) - addSubview(labelContainer) + containerStackView.addArrangedSubview(imageView) + containerStackView.addArrangedSubview(labelStackView) + containerStackView.isUserInteractionEnabled = false + + addSubview(containerStackView) addSubview(highlightView) - subviews.forEach { $0.isUserInteractionEnabled = false } - - labelContainer.translatesAutoresizingMaskIntoConstraints = false - titleLabel.translatesAutoresizingMaskIntoConstraints = false - linkLabel.translatesAutoresizingMaskIntoConstraints = false - imageView.translatesAutoresizingMaskIntoConstraints = false + containerStackView.translatesAutoresizingMaskIntoConstraints = false highlightView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - titleLabel.topAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.topAnchor), - titleLabel.leadingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.leadingAnchor), - titleLabel.trailingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.trailingAnchor), - - linkLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 2), - linkLabel.bottomAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.bottomAnchor), - linkLabel.leadingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.leadingAnchor), - linkLabel.trailingAnchor.constraint(equalTo: labelContainer.layoutMarginsGuide.trailingAnchor), - - labelContainer.trailingAnchor.constraint(equalTo: trailingAnchor), - - imageView.topAnchor.constraint(equalTo: topAnchor), - imageView.leadingAnchor.constraint(equalTo: leadingAnchor), - - highlightView.topAnchor.constraint(equalTo: topAnchor), - highlightView.bottomAnchor.constraint(equalTo: bottomAnchor), - highlightView.leadingAnchor.constraint(equalTo: leadingAnchor), - highlightView.trailingAnchor.constraint(equalTo: trailingAnchor), - ]) + containerStackView.pinToParent() + highlightView.pinToParent() } required init?(coder: NSCoder) { @@ -129,19 +111,24 @@ public final class LinkPreviewButton: UIControl { ) { [weak imageView] image, _, _, _ in if image != nil { imageView?.contentMode = .scaleAspectFill + self.containerStackView.setNeedsLayout() + self.containerStackView.layoutIfNeeded() } } NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints) if isCompact { + containerStackView.alignment = .center + containerStackView.axis = .horizontal + containerStackView.distribution = .fill NSLayoutConstraint.activate(compactImageConstraints) } else { + containerStackView.alignment = .fill + containerStackView.axis = .vertical + containerStackView.distribution = .equalSpacing NSLayoutConstraint.activate(largeImageConstraints) } - - setNeedsLayout() - layoutIfNeeded() } public override func didMoveToWindow() { @@ -166,3 +153,7 @@ public final class LinkPreviewButton: UIControl { imageView.backgroundColor = theme.systemElevatedBackgroundColor } } + +private extension UILayoutPriority { + static let zero = UILayoutPriority(rawValue: 0) +} From 4616d405190fc944c23c20628ca548e7a20d258c Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 19:22:05 -0800 Subject: [PATCH 231/733] More spacing --- MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 642ac3007..070bbc92e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -388,7 +388,7 @@ extension StatusView.Style { // content container: V - [ contentMetaText ] statusView.contentContainer.axis = .vertical - statusView.contentContainer.spacing = 10 + statusView.contentContainer.spacing = 12 statusView.contentContainer.distribution = .fill statusView.contentContainer.alignment = .fill From 03918301fbc580e5f2f70a604b23dd9bf251b335 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 19:26:10 -0800 Subject: [PATCH 232/733] Space buttons instead of stretching --- .../MastodonUI/View/Control/ActionToolbarContainer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift index 446b4af2a..73695b782 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift @@ -105,7 +105,7 @@ extension ActionToolbarContainer { shareButton.setImage(ActionToolbarContainer.shareImage, for: .normal) container.axis = .horizontal - container.distribution = .fill + container.distribution = .equalSpacing replyButton.translatesAutoresizingMaskIntoConstraints = false reblogButton.translatesAutoresizingMaskIntoConstraints = false From 3a90b1c8652b40042ad619978ba1163d56757012 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 21:47:49 -0800 Subject: [PATCH 233/733] Change name and improve a11y --- ...ewButton.swift => StatusCardControl.swift} | 26 ++++++++++++++----- .../View/Content/StatusView+ViewModel.swift | 6 ++--- .../MastodonUI/View/Content/StatusView.swift | 25 ++++++++---------- 3 files changed, 33 insertions(+), 24 deletions(-) rename MastodonSDK/Sources/MastodonUI/View/Content/{LinkPreviewButton.swift => StatusCardControl.swift} (87%) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift similarity index 87% rename from MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift rename to MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index db700cca1..3ff39be60 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/LinkPreviewButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -12,7 +12,7 @@ import MastodonCore import CoreDataStack import UIKit -public final class LinkPreviewButton: UIControl { +public final class StatusCardControl: UIControl { private var disposeBag = Set() private let containerStackView = UIStackView() @@ -25,21 +25,23 @@ public final class LinkPreviewButton: UIControl { private lazy var compactImageConstraints = [ imageView.heightAnchor.constraint(equalTo: heightAnchor), - imageView.widthAnchor.constraint(equalTo: heightAnchor), - heightAnchor.constraint(equalToConstant: 85), + imageView.widthAnchor.constraint(equalToConstant: 85), + heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1), + heightAnchor.constraint(greaterThanOrEqualToConstant: 85) ] private lazy var largeImageConstraints = [ imageView.heightAnchor.constraint( equalTo: imageView.widthAnchor, multiplier: 21 / 40 - ).priority(.defaultLow - 1), + ) + // This priority is important or constraints break; + // it still renders the card correctly. + .priority(.defaultLow - 1), ] public override var isHighlighted: Bool { - didSet { - highlightView.isHidden = !isHighlighted - } + didSet { highlightView.isHidden = !isHighlighted } } public override init(frame: CGRect) { @@ -55,6 +57,10 @@ public final class LinkPreviewButton: UIControl { layer.cornerCurve = .continuous layer.cornerRadius = 10 + if #available(iOS 15, *) { + maximumContentSizeCategory = .accessibilityLarge + } + highlightView.backgroundColor = UIColor.black.withAlphaComponent(0.1) highlightView.isHidden = true @@ -101,6 +107,12 @@ public final class LinkPreviewButton: UIControl { public func configure(card: Card) { let isCompact = card.width == card.height + if let host = card.url?.host { + accessibilityLabel = "\(card.title) \(host)" + } else { + accessibilityLabel = card.title + } + titleLabel.text = card.title linkLabel.text = card.url?.host imageView.contentMode = .center diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index af6a1a680..77de106b1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -316,7 +316,7 @@ extension StatusView.ViewModel { } statusView.contentMetaText.textView.alpha = isContentReveal ? 1 : 0 // keep the frame size and only display when revealing - statusView.linkPreviewButton.alpha = isContentReveal ? 1 : 0 + statusView.statusCardControl.alpha = isContentReveal ? 1 : 0 statusView.setSpoilerOverlayViewHidden(isHidden: isContentReveal) @@ -490,8 +490,8 @@ extension StatusView.ViewModel { private func bindCard(statusView: StatusView) { $card.sink { card in guard let card = card else { return } - statusView.linkPreviewButton.configure(card: card) - statusView.setLinkPreviewButtonDisplay() + statusView.statusCardControl.configure(card: card) + statusView.setStatusCardControlDisplay() } .store(in: &disposeBag) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 070bbc92e..249e2e1ec 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -115,7 +115,7 @@ public final class StatusView: UIView { return metaText }() - public let linkPreviewButton = LinkPreviewButton() + public let statusCardControl = StatusCardControl() // content warning public let spoilerOverlayView = SpoilerOverlayView() @@ -220,7 +220,7 @@ public final class StatusView: UIView { setMediaDisplay(isDisplay: false) setPollDisplay(isDisplay: false) setFilterHintLabelDisplay(isDisplay: false) - setLinkPreviewButtonDisplay(isDisplay: false) + setStatusCardControlDisplay(isDisplay: false) } public override init(frame: CGRect) { @@ -261,16 +261,13 @@ extension StatusView { // content contentMetaText.textView.delegate = self contentMetaText.textView.linkDelegate = self - + + // card + statusCardControl.addTarget(self, action: #selector(statusCardControlPressed), for: .touchUpInside) + // media mediaGridContainerView.delegate = self - linkPreviewButton.addTarget( - self, - action: #selector(linkPreviewButtonPressed), - for: .touchUpInside - ) - // poll pollTableView.translatesAutoresizingMaskIntoConstraints = false pollTableViewHeightLayoutConstraint = pollTableView.heightAnchor.constraint(equalToConstant: 44.0).priority(.required - 1) @@ -306,7 +303,7 @@ extension StatusView { delegate?.statusView(self, spoilerOverlayViewDidPressed: spoilerOverlayView) } - @objc private func linkPreviewButtonPressed(_ sender: LinkPreviewButton) { + @objc private func statusCardControlPressed(_ sender: StatusCardControl) { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") guard let url = viewModel.card?.url else { return } delegate?.statusView(self, didTapCardWithURL: url) @@ -386,7 +383,7 @@ extension StatusView.Style { statusView.authorAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin statusView.containerStackView.addArrangedSubview(statusView.authorAdaptiveMarginContainerView) - // content container: V - [ contentMetaText ] + // content container: V - [ contentMetaText statusCardControl ] statusView.contentContainer.axis = .vertical statusView.contentContainer.spacing = 12 statusView.contentContainer.distribution = .fill @@ -400,7 +397,7 @@ extension StatusView.Style { // status content statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView) - statusView.contentContainer.addArrangedSubview(statusView.linkPreviewButton) + statusView.contentContainer.addArrangedSubview(statusView.statusCardControl) statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false statusView.containerStackView.addSubview(statusView.spoilerOverlayView) @@ -542,8 +539,8 @@ extension StatusView { filterHintLabel.isHidden = !isDisplay } - func setLinkPreviewButtonDisplay(isDisplay: Bool = true) { - linkPreviewButton.isHidden = !isDisplay + func setStatusCardControlDisplay(isDisplay: Bool = true) { + statusCardControl.isHidden = !isDisplay } // container width From 8a8ecb0b686a4707e1435e4129c8f345a414f62b Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 22:05:43 -0800 Subject: [PATCH 234/733] Improve layout --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 3ff39be60..7dabe9bf6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -89,6 +89,7 @@ public final class StatusCardControl: UIControl { containerStackView.addArrangedSubview(imageView) containerStackView.addArrangedSubview(labelStackView) containerStackView.isUserInteractionEnabled = false + containerStackView.distribution = .fill addSubview(containerStackView) addSubview(highlightView) @@ -133,12 +134,10 @@ public final class StatusCardControl: UIControl { if isCompact { containerStackView.alignment = .center containerStackView.axis = .horizontal - containerStackView.distribution = .fill NSLayoutConstraint.activate(compactImageConstraints) } else { containerStackView.alignment = .fill containerStackView.axis = .vertical - containerStackView.distribution = .equalSpacing NSLayoutConstraint.activate(largeImageConstraints) } } From 176067800c0239a3d4feb3d12d23e7eb71c21583 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 23:42:02 -0800 Subject: [PATCH 235/733] Add card when merging --- .../CoreDataStack/Entity/Mastodon/Card.swift | 6 ++- .../Persistence/Persistence+Status.swift | 39 ++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift index 99f53f268..d656191f9 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift @@ -50,7 +50,7 @@ public final class Card: NSManagedObject { // sourcery: autoGenerateProperty @NSManaged public private(set) var blurhash: String? - // one-to-one relationship + // sourcery: autoGenerateRelationship @NSManaged public private(set) var status: Status } @@ -157,13 +157,17 @@ extension Card: AutoGenerateRelationship { // Generated using Sourcery // DO NOT EDIT public struct Relationship { + public let status: Status public init( + status: Status ) { + self.status = status } } public func configure(relationship: Relationship) { + self.status = relationship.status } // sourcery:end diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift index 97ab32e30..aa5eb8546 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Status.swift @@ -87,7 +87,7 @@ extension Persistence.Status { } if let oldStatus = fetch(in: managedObjectContext, context: context) { - merge(mastodonStatus: oldStatus, context: context) + merge(in: managedObjectContext, mastodonStatus: oldStatus, context: context) return PersistResult( status: oldStatus, isNewInsertion: false, @@ -108,18 +108,7 @@ extension Persistence.Status { return result.poll }() - let card: Card? = { - guard let entity = context.entity.card else { return nil } - let result = Persistence.Card.create( - in: managedObjectContext, - context: Persistence.Card.PersistContext( - domain: context.domain, - entity: entity, - me: context.me - ) - ) - return result.card - }() + let card = createCard(in: managedObjectContext, context: context) let authorResult = Persistence.MastodonUser.createOrMerge( in: managedObjectContext, @@ -196,6 +185,7 @@ extension Persistence.Status { } public static func merge( + in managedObjectContext: NSManagedObjectContext, mastodonStatus status: Status, context: PersistContext ) { @@ -217,8 +207,31 @@ extension Persistence.Status { ) ) } + + if status.card == nil, context.entity.card != nil { + let card = createCard(in: managedObjectContext, context: context) + let relationship = Card.Relationship(status: status) + card?.configure(relationship: relationship) + } + update(status: status, context: context) } + + private static func createCard( + in managedObjectContext: NSManagedObjectContext, + context: PersistContext + ) -> Card? { + guard let entity = context.entity.card else { return nil } + let result = Persistence.Card.create( + in: managedObjectContext, + context: Persistence.Card.PersistContext( + domain: context.domain, + entity: entity, + me: context.me + ) + ) + return result.card + } private static func update( status: Status, From 459564ae6badc92ecf20a328e11f17849698d650 Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sat, 26 Nov 2022 23:49:51 -0800 Subject: [PATCH 236/733] Update table view --- .../StatusTableViewCell+ViewModel.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell+ViewModel.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell+ViewModel.swift index 85184d406..2702d726b 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell+ViewModel.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell+ViewModel.swift @@ -67,6 +67,21 @@ extension StatusTableViewCell { } } .store(in: &disposeBag) + + statusView.viewModel.$card + .removeDuplicates() + .dropFirst() + .receive(on: DispatchQueue.main) + .sink { [weak tableView, weak self] _ in + guard let tableView = tableView else { return } + guard let _ = self else { return } + + UIView.performWithoutAnimation { + tableView.beginUpdates() + tableView.endUpdates() + } + } + .store(in: &disposeBag) } } From b03f14a9c66538eaa74e49c6ee4051c9e7b27104 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 27 Nov 2022 15:33:24 +0100 Subject: [PATCH 237/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 1b1a81e81..00c5b735f 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Startseite", "search": "Suche", - "notifications": "Notifications", + "notifications": "Mitteilungen", "profile": "Profil" }, "keyboard": { From 61a07e9a5b308177dbf859ac843f7d9a0a99a24b Mon Sep 17 00:00:00 2001 From: Kyle Bashour Date: Sun, 27 Nov 2022 21:00:03 -0800 Subject: [PATCH 238/733] Layout improvements --- .../View/Content/StatusCardControl.swift | 103 +++++++++++------- 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 7dabe9bf6..6b3e00189 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -23,22 +23,8 @@ public final class StatusCardControl: UIControl { private let titleLabel = UILabel() private let linkLabel = UILabel() - private lazy var compactImageConstraints = [ - imageView.heightAnchor.constraint(equalTo: heightAnchor), - imageView.widthAnchor.constraint(equalToConstant: 85), - heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1), - heightAnchor.constraint(greaterThanOrEqualToConstant: 85) - ] - - private lazy var largeImageConstraints = [ - imageView.heightAnchor.constraint( - equalTo: imageView.widthAnchor, - multiplier: 21 / 40 - ) - // This priority is important or constraints break; - // it still renders the card correctly. - .priority(.defaultLow - 1), - ] + private var layout: Layout? + private var layoutConstraints: [NSLayoutConstraint] = [] public override var isHighlighted: Bool { didSet { highlightView.isHidden = !isHighlighted } @@ -85,6 +71,7 @@ public final class StatusCardControl: UIControl { labelStackView.layoutMargins = .init(top: 10, left: 10, bottom: 10, right: 10) labelStackView.isLayoutMarginsRelativeArrangement = true labelStackView.axis = .vertical + labelStackView.spacing = 2 containerStackView.addArrangedSubview(imageView) containerStackView.addArrangedSubview(labelStackView) @@ -106,8 +93,6 @@ public final class StatusCardControl: UIControl { } public func configure(card: Card) { - let isCompact = card.width == card.height - if let host = card.url?.host { accessibilityLabel = "\(card.title) \(host)" } else { @@ -120,26 +105,17 @@ public final class StatusCardControl: UIControl { imageView.sd_setImage( with: card.imageURL, - placeholderImage: isCompact ? newsIcon : photoIcon - ) { [weak imageView] image, _, _, _ in + placeholderImage: icon(for: card.layout) + ) { [weak self] image, _, _, _ in if image != nil { - imageView?.contentMode = .scaleAspectFill - self.containerStackView.setNeedsLayout() - self.containerStackView.layoutIfNeeded() + self?.imageView.contentMode = .scaleAspectFill } + + self?.containerStackView.setNeedsLayout() + self?.containerStackView.layoutIfNeeded() } - NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints) - - if isCompact { - containerStackView.alignment = .center - containerStackView.axis = .horizontal - NSLayoutConstraint.activate(compactImageConstraints) - } else { - containerStackView.alignment = .fill - containerStackView.axis = .vertical - NSLayoutConstraint.activate(largeImageConstraints) - } + updateConstraints(for: card.layout) } public override func didMoveToWindow() { @@ -150,13 +126,47 @@ public final class StatusCardControl: UIControl { } } - private var newsIcon: UIImage? { - UIImage(systemName: "newspaper.fill") + private func updateConstraints(for layout: Layout) { + guard layout != self.layout else { return } + self.layout = layout + + NSLayoutConstraint.deactivate(layoutConstraints) + + switch layout { + case .large(let aspectRatio): + containerStackView.alignment = .fill + containerStackView.axis = .vertical + layoutConstraints = [ + imageView.widthAnchor.constraint( + equalTo: imageView.heightAnchor, + multiplier: aspectRatio + ) + // This priority is important or constraints break; + // it still renders the card correctly. + .priority(.defaultLow - 1), + ] + case .compact: + containerStackView.alignment = .center + containerStackView.axis = .horizontal + layoutConstraints = [ + imageView.heightAnchor.constraint(equalTo: heightAnchor), + imageView.widthAnchor.constraint(equalToConstant: 85), + heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1), + heightAnchor.constraint(greaterThanOrEqualToConstant: 85) + ] + } + + NSLayoutConstraint.activate(layoutConstraints) } - private var photoIcon: UIImage? { - let configuration = UIImage.SymbolConfiguration(pointSize: 32) - return UIImage(systemName: "photo", withConfiguration: configuration) + private func icon(for layout: Layout) -> UIImage? { + switch layout { + case .compact: + return UIImage(systemName: "newspaper.fill") + case .large: + let configuration = UIImage.SymbolConfiguration(pointSize: 32) + return UIImage(systemName: "photo", withConfiguration: configuration) + } } private func apply(theme: Theme) { @@ -165,6 +175,21 @@ public final class StatusCardControl: UIControl { } } +private extension StatusCardControl { + enum Layout: Equatable { + case compact + case large(aspectRatio: CGFloat) + } +} + +private extension Card { + var layout: StatusCardControl.Layout { + return width == height || image == nil + ? .compact + : .large(aspectRatio: CGFloat(width) / CGFloat(height)) + } +} + private extension UILayoutPriority { static let zero = UILayoutPriority(rawValue: 0) } From 9c06e49e72c91f71282cd74464cd30fd024f8a04 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Nov 2022 09:39:42 +0100 Subject: [PATCH 239/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index fccba95bc..889d8d8e1 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "Heim", "search": "Leita", - "notifications": "Notifications", + "notifications": "Tilkynningar", "profile": "Notandasnið" }, "keyboard": { From 215a7df2976fc942b5f5be4ff5221cdf15b62c13 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Nov 2022 09:39:43 +0100 Subject: [PATCH 240/733] New translations app.json (Hebrew) --- .../StringsConvertor/input/he.lproj/app.json | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index c757b4979..32bd75cdf 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -75,7 +75,7 @@ "save_photo": "Save Photo", "copy_photo": "Copy Photo", "sign_in": "Log in", - "sign_up": "Create account", + "sign_up": "יצירת חשבון", "see_more": "See More", "preview": "Preview", "share": "Share", @@ -88,16 +88,16 @@ "skip": "Skip", "reply": "Reply", "report_user": "Report %s", - "block_domain": "Block %s", - "unblock_domain": "Unblock %s", - "settings": "Settings", + "block_domain": "חסימת %s", + "unblock_domain": "הסרת חסימה מ־%s", + "settings": "הגדרות", "delete": "Delete" }, "tabs": { "home": "Home", "search": "Search", "notifications": "Notifications", - "profile": "Profile" + "profile": "פרופיל" }, "keyboard": { "common": { @@ -129,7 +129,7 @@ "show_post": "Show Post", "show_user_profile": "Show user profile", "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", + "sensitive_content": "תוכן רגיש", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", "poll": { @@ -143,7 +143,7 @@ "email": "Email address: %s" }, "actions": { - "reply": "Reply", + "reply": "תגובה", "reblog": "Reblog", "unreblog": "Undo reblog", "favorite": "Favorite", @@ -215,7 +215,7 @@ "scene": { "welcome": { "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", + "get_started": "בואו נתחיל", "log_in": "Log In" }, "login": { @@ -233,16 +233,16 @@ "all": "All", "all_accessiblity_description": "Category: All", "academia": "academia", - "activism": "activism", - "food": "food", + "activism": "אקטיביזם", + "food": "אוכל", "furry": "furry", - "games": "games", - "general": "general", + "games": "משחקים", + "general": "כללי", "journalism": "journalism", - "lgbt": "lgbt", + "lgbt": "להט\"ב", "regional": "regional", - "art": "art", - "music": "music", + "art": "אומנות", + "music": "מוזיקה", "tech": "tech" }, "see_less": "See Less", @@ -270,17 +270,17 @@ "delete": "Delete" }, "username": { - "placeholder": "username", + "placeholder": "שם משתמש/ת", "duplicate_prompt": "This username is taken." }, "display_name": { - "placeholder": "display name" + "placeholder": "שם תצוגה" }, "email": { - "placeholder": "email" + "placeholder": "דוא״ל" }, "password": { - "placeholder": "password", + "placeholder": "סיסמה", "require": "Your password needs at least:", "character_limit": "8 characters", "accessibility": { @@ -295,9 +295,9 @@ }, "error": { "item": { - "username": "Username", - "email": "Email", - "password": "Password", + "username": "שם משתמש/ת", + "email": "דוא״ל", + "password": "סיסמה", "agreement": "Agreement", "locale": "Locale", "reason": "Reason" @@ -397,12 +397,12 @@ }, "poll": { "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", - "three_days": "3 Days", - "seven_days": "7 Days", + "thirty_minutes": "חצי שעה", + "one_hour": "שעה", + "six_hours": "6 שעות", + "one_day": "יום אחד", + "three_days": "3 ימים", + "seven_days": "7 ימים", "option_number": "Option %ld", "the_poll_is_invalid": "The poll is invalid", "the_poll_has_empty_option": "The poll has empty option" @@ -413,7 +413,7 @@ "visibility": { "public": "Public", "unlisted": "Unlisted", - "private": "Followers only", + "private": "לעוקבים בלבד", "direct": "Only people I mention" }, "auto_complete": { From 248d0a5570c99de2a195fd3b767d0af6722d99fc Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 29 Nov 2022 11:51:28 +0100 Subject: [PATCH 241/733] fix: Text in compose post is not selectable, focussable, pastable --- .../Scene/ComposeContent/Attachment/AttachmentView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentView.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentView.swift index 9346c3bee..edf05b49c 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentView.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentView.swift @@ -30,6 +30,7 @@ public struct AttachmentView: View { Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fill) + .allowsHitTesting(false) } ) .overlay( From 2683ae3ca16330b1acb02cb845fab5fecc37667d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 29 Nov 2022 16:55:30 +0100 Subject: [PATCH 242/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index a6d1c3f2b..f80f96c79 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -96,7 +96,7 @@ "tabs": { "home": "အိမ်", "search": "ရှာဖွေရန်", - "notifications": "Notifications", + "notifications": "အသိပေးချက်များ", "profile": "ကိုယ်ရေးမှတ်တမ်း" }, "keyboard": { @@ -306,19 +306,19 @@ "blocked": "%s တွင် ခွင့်မပြုထားသော အီးမေးလ်ထောက်ပံ့သူပါဝင်နေသည်။", "unreachable": "%s တည်ရှိပုံ မပေါ်ပါ", "taken": "%s ကို အသုံးပြုနေသူ ရှိနှင့်ပြီးဖြစ်သည်။", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", - "blank": "%s is required", - "invalid": "%s is invalid", - "too_long": "%s is too long", - "too_short": "%s is too short", - "inclusion": "%s is not a supported value" + "reserved": "%s သည် သီးသန့်ဖယ်ထားသောစကားလုံး ဖြစ်သည်။", + "accepted": "%s ကို လက်ခံရမည်ဖြစ်သည်", + "blank": "%s ကို လိုအပ်သည်", + "invalid": "%s သည် မခိုင်လုံပါ", + "too_long": "%s သည် ရှည်လွန်းသည်", + "too_short": "%s သည် တိုလွန်းသည်", + "inclusion": "%s သည် ထောက်ပံ့ထားသောတန်ဖိုး မဟုတ်ပါ" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", - "password_too_short": "Password is too short (must be at least 8 characters)" + "username_invalid": "အသုံးပြုသူအမည်တွင် ဂဏန်းအက္ခရာစာလုံးနှင့် အောက်မျဉ်း သာလျှင် ပါဝင်နိုင်သည်", + "username_too_long": "အသုံးပြုသူအမည်ရှည်လွန်းသည် (စာလုံး ၃၀ လုံးထက် ရှည်၍ မရပါ)", + "email_invalid": "ဤအီးမေးလ်လိပ်စာသည် ခိုင်လုံမှု မရှိပါ", + "password_too_short": "စကားဝှက်တိုလွန်းသည် (အနည်းဆုံး စာလုံး ၈ လုံး ရှိရမည်)" } } }, From 6fd2558876462c06a9180a6ef5c671039b217282 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 29 Nov 2022 18:14:21 +0100 Subject: [PATCH 243/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 889d8d8e1..b3ce68632 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -206,8 +206,8 @@ "user_blocking_warning": "Þú getur ekki séð sniðið hjá %s\nfyrr en þú hættir að útiloka hann.\nSniðið þitt lítur svona út hjá honum.", "blocked_warning": "Þú getur ekki séð sniðið hjá þessum notanda\nfyrr en hann hættir að útiloka þig.", "user_blocked_warning": "Þú getur ekki séð sniðið hjá %s\nfyrr en hann hættir að útiloka þig.", - "suspended_warning": "Þessi notandi hefur verið settur í bið.", - "user_suspended_warning": "Notandaaðgangurinn %s hefur verið settur í bið." + "suspended_warning": "Þessi notandi hefur verið settur í frysti.", + "user_suspended_warning": "Notandaaðgangurinn %s hefur verið settur í frysti." } } } From ca87116d57900a75ac3ded8044ec15318aa03edc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 29 Nov 2022 18:14:23 +0100 Subject: [PATCH 244/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index f80f96c79..5877396f2 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -323,44 +323,44 @@ } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "title": "အခြေခံမှုအချို့", + "subtitle": "ဤစည်းမျဉ်းများကို ထိန်းညှိသူ %s ယောက်က သတ်မှတ်ကွပ်ကဲသည်။", + "prompt": "ဆက်လက်သွားမည်ဆိုပါက သင်သည် %s အတွက် ဝန်ဆောင်မှုနှင့် ကိုယ်ရေးကိုယ်တာမူဝါဒများကို လိုက်နာရမည်ဖြစ်သည်။", + "terms_of_service": "ဝန်ဆောင်မှုစည်းကမ်းချက်များ", + "privacy_policy": "ကိုယ်ရေးကိုယ်တာမူဝါဒ", "button": { - "confirm": "I Agree" + "confirm": "သဘောတူညီသည်" } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "title": "နောက််ဆုံးတစ်ခု", + "subtitle": "သင့်ကို ပို့လိုက်သောအီးမေးလ်တွင် ပါဝင်သည့်လင့်ခ်ကို နှိပ်ပါ။", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "သင့်ကို ပို့လိုက်သောအီးမေးလ်တွင် ပါဝင်သည့်လင့်ခ်ကို နှိပ်ပါ။", "button": { - "open_email_app": "Open Email App", - "resend": "Resend" + "open_email_app": "အီးမေးလ်ကို ဖွင့်ပါ", + "resend": "ပြန်ပို့ပါ" }, "dont_receive_email": { - "title": "Check your email", + "title": "သင့်အီးမေးလ်ကို စစ်ကြည့်ပါ", "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "resend_email": "အီးမေးလ်ကိုပြန်ပို့ပါ" }, "open_email_app": { - "title": "Check your inbox.", + "title": "သင်၏စာဝင်ပုံးကို စစ်ဆေးပါ", "description": "We just sent you an email. Check your junk folder if you haven’t.", - "mail": "Mail", + "mail": "မေးလ်", "open_email_client": "Open Email Client" } }, "home_timeline": { - "title": "Home", + "title": "အိမ်", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "အော့ဖ်လိုင်း", + "new_posts": "ပို့စ်အသစ်ကြည့်ရန်", + "published": "တင်လိုက်ပါပြီ!", + "Publishing": "ပို့စ်ကို တင်နေသည်...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "လိုဂိုခလုတ်", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -371,20 +371,20 @@ }, "compose": { "title": { - "new_post": "New Post", - "new_reply": "New Reply" + "new_post": "ပို့စ်အသစ်", + "new_reply": "စာပြန်အသစ်" }, "media_selection": { - "camera": "Take Photo", - "photo_library": "Photo Library", - "browse": "Browse" + "camera": "ဓါတ်ပုံရိုက်", + "photo_library": "ဓာတ်ပုံပြတိုက်", + "browse": "ရှာဖွေ" }, "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", + "compose_action": "ပို့စ်တင်", + "replying_to_user": "%s ထံ စာပြန်နေသည်", "attachment": { - "photo": "photo", - "video": "video", + "photo": "ဓာတ်ပုံ", + "video": "ဗီဒီယို", "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", "description_photo": "Describe the photo for the visually-impaired...", "description_video": "Describe the video for the visually-impaired...", From 22edb12135830c06fc33aab3b4dfdbb507a2c57c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 30 Nov 2022 12:01:22 +0100 Subject: [PATCH 245/733] New translations app.json (Romanian) --- .../StringsConvertor/input/ro.lproj/app.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index b6e399f8b..f65c3b1be 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -13,7 +13,7 @@ }, "vote_failure": { "title": "Eșec la vot", - "poll_ended": "The poll has ended" + "poll_ended": "Sondajul tău s-a încheiat" }, "discard_post_content": { "title": "Șterge Schită", @@ -41,7 +41,7 @@ "block_entire_domain": "Block Domain" }, "save_photo_failure": { - "title": "Save Photo Failure", + "title": "Salvarea fotografiei a eșuat", "message": "Please enable the photo library access permission to save the photo." }, "delete_post": { @@ -55,13 +55,13 @@ }, "controls": { "actions": { - "back": "Back", - "next": "Next", + "back": "Înapoi", + "next": "Înainte", "previous": "Previous", "open": "Deschide", - "add": "Add", + "add": "Adaugă", "remove": "Elimină", - "edit": "Edit", + "edit": "Modifică", "save": "Salvează", "ok": "OK", "done": "Done", @@ -82,10 +82,10 @@ "share_user": "Share %s", "share_post": "Share Post", "open_in_safari": "Open in Safari", - "open_in_browser": "Open in Browser", - "find_people": "Find people to follow", + "open_in_browser": "Deschide în browser", + "find_people": "Găsește persoane de urmărit", "manually_search": "Manually search instead", - "skip": "Skip", + "skip": "Treci peste", "reply": "Reply", "report_user": "Report %s", "block_domain": "Block %s", @@ -94,7 +94,7 @@ "delete": "Delete" }, "tabs": { - "home": "Home", + "home": "Acasă", "search": "Search", "notifications": "Notifications", "profile": "Profile" From 2003e4987cfa4869a502f9074a03b53f8ff1c81a Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Nov 2022 09:09:24 -0500 Subject: [PATCH 246/733] =?UTF-8?q?Rename=20second=20tab=20to=20=E2=80=9CS?= =?UTF-8?q?earch=20and=20Explore=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Localization/StringsConvertor/input/Base.lproj/app.json | 2 +- Localization/app.json | 2 +- Mastodon/Scene/Root/MainTab/MainTabBarController.swift | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++-- .../Resources/Base.lproj/Localizable.strings | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index ea046bfbc..df1a45fe1 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, diff --git a/Localization/app.json b/Localization/app.json index ea046bfbc..df1a45fe1 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index a2778b551..07a187188 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -61,7 +61,7 @@ class MainTabBarController: UITabBarController { var title: String { switch self { case .home: return L10n.Common.Controls.Tabs.home - case .search: return L10n.Common.Controls.Tabs.search + case .search: return L10n.Common.Controls.Tabs.searchAndExplore case .compose: return L10n.Common.Controls.Actions.compose case .notifications: return L10n.Common.Controls.Tabs.notifications case .me: return L10n.Common.Controls.Tabs.profile diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 0392d2b05..3dd0a025e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -370,8 +370,8 @@ public enum L10n { public static let notifications = L10n.tr("Localizable", "Common.Controls.Tabs.Notifications", fallback: "Notifications") /// Profile public static let profile = L10n.tr("Localizable", "Common.Controls.Tabs.Profile", fallback: "Profile") - /// Search - public static let search = L10n.tr("Localizable", "Common.Controls.Tabs.Search", fallback: "Search") + /// Search and Explore + public static let searchAndExplore = L10n.tr("Localizable", "Common.Controls.Tabs.SearchAndExplore", fallback: "Search and Explore") } public enum Timeline { /// Filtered diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index adeaad07b..089f0fa8e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -133,7 +133,7 @@ Please check your internet connection."; "Common.Controls.Tabs.Home" = "Home"; "Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profile"; -"Common.Controls.Tabs.Search" = "Search"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Filtered"; "Common.Controls.Timeline.Header.BlockedWarning" = "You can’t view this user’s profile until they unblock you."; From 8db551837ccd5860ffed2df97bb72b27c12a7db6 Mon Sep 17 00:00:00 2001 From: Jordan Kay Date: Wed, 30 Nov 2022 17:22:17 -0500 Subject: [PATCH 247/733] Remove unused file --- Mastodon.xcodeproj/project.pbxproj | 4 -- Mastodon/Extension/ActiveLabel.swift | 66 ---------------------------- 2 files changed, 70 deletions(-) delete mode 100644 Mastodon/Extension/ActiveLabel.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0c43b71df..ba4203f5e 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -66,7 +66,6 @@ 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */; }; 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; }; 2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */; }; - 2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF123A625C3B0210020F248 /* ActiveLabel.swift */; }; 5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */; }; 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */; }; 5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B90C456262599800002E742 /* SettingsViewModel.swift */; }; @@ -564,7 +563,6 @@ 2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountTableViewCell.swift; sourceTree = ""; }; 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendCollectionHeader.swift; sourceTree = ""; }; 2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountSection.swift; sourceTree = ""; }; - 2DF123A625C3B0210020F248 /* ActiveLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveLabel.swift; sourceTree = ""; }; 2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = ""; }; 3B7FD8F28DDA8FBCE5562B78 /* Pods-NotificationService.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk - debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk - debug.xcconfig"; sourceTree = ""; }; 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2225,7 +2223,6 @@ DB8AF56225C138BC002E6C99 /* Extension */ = { isa = PBXGroup; children = ( - 2DF123A625C3B0210020F248 /* ActiveLabel.swift */, 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */, 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */, 2D206B8525F5FB0900143C56 /* Double.swift */, @@ -3273,7 +3270,6 @@ DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */, DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */, DB5B729E273113F300081888 /* FollowingListViewModel+State.swift in Sources */, - 2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */, DBF9814C265E339500E4BA07 /* ProfileFieldAddEntryCollectionViewCell.swift in Sources */, DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */, DB73BF4927140BA300781945 /* UICollectionViewDiffableDataSource.swift in Sources */, diff --git a/Mastodon/Extension/ActiveLabel.swift b/Mastodon/Extension/ActiveLabel.swift deleted file mode 100644 index 4b23d4eb3..000000000 --- a/Mastodon/Extension/ActiveLabel.swift +++ /dev/null @@ -1,66 +0,0 @@ -//extension ActiveEntity { -// -// var accessibilityLabelDescription: String { -// switch self.type { -// case .email: return L10n.Common.Controls.Status.Tag.email -// case .hashtag: return L10n.Common.Controls.Status.Tag.hashtag -// case .mention: return L10n.Common.Controls.Status.Tag.mention -// case .url: return L10n.Common.Controls.Status.Tag.url -// case .emoji: return L10n.Common.Controls.Status.Tag.emoji -// } -// } -// -// var accessibilityValueDescription: String { -// switch self.type { -// case .email(let text, _): return text -// case .hashtag(let text, _): return text -// case .mention(let text, _): return text -// case .url(_, let trimmed, _, _): return trimmed -// case .emoji(let text, _, _): return text -// } -// } -// -// func accessibilityElement(in accessibilityContainer: Any) -> ActiveLabelAccessibilityElement? { -// if case .emoji = self.type { -// return nil -// } -// -// let element = ActiveLabelAccessibilityElement(accessibilityContainer: accessibilityContainer) -// element.accessibilityTraits = .button -// element.accessibilityLabel = accessibilityLabelDescription -// element.accessibilityValue = accessibilityValueDescription -// return element -// } -//} - -//final class ActiveLabelAccessibilityElement: UIAccessibilityElement { -// var index: Int! -//} -// -// MARK: - UIAccessibilityContainer -//extension ActiveLabel { -// -// func createAccessibilityElements() -> [UIAccessibilityElement] { -// var elements: [UIAccessibilityElement] = [] -// -// let element = ActiveLabelAccessibilityElement(accessibilityContainer: self) -// element.accessibilityTraits = .staticText -// element.accessibilityLabel = accessibilityLabel -// element.accessibilityFrame = superview!.convert(frame, to: nil) -// element.accessibilityLanguage = accessibilityLanguage -// elements.append(element) -// -// for entity in activeEntities { -// guard let element = entity.accessibilityElement(in: self) else { continue } -// var glyphRange = NSRange() -// layoutManager.characterRange(forGlyphRange: entity.range, actualGlyphRange: &glyphRange) -// let rect = layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer) -// element.accessibilityFrame = self.convert(rect, to: nil) -// element.accessibilityContainer = self -// elements.append(element) -// } -// -// return elements -// } -// -//} From fd9a253fac5311c9096c1352f4d8c41eb2b8303b Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 1 Dec 2022 15:29:56 +0800 Subject: [PATCH 248/733] fix: workaround paste crash on iOS 14.x issue --- .../Vendor/MetaTextView+PasteExtensions.swift | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift b/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift index 8fe1949af..12e6632a7 100644 --- a/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift +++ b/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift @@ -13,17 +13,21 @@ extension MetaTextView { public override func paste(_ sender: Any?) { super.paste(sender) - var nextResponder = self.next; - - // Force the event to bubble through ALL responders - // This is a workaround as somewhere down the chain the paste event gets eaten - while (nextResponder != nil) { - if let nextResponder = nextResponder { - if (nextResponder.responds(to: #selector(UIResponderStandardEditActions.paste(_:)))) { - nextResponder.perform(#selector(UIResponderStandardEditActions.paste(_:)), with: sender) + // fix #660 + // https://github.com/mastodon/mastodon-ios/issues/660 + if #available(iOS 15.0, *) { + var nextResponder = self.next; + + // Force the event to bubble through ALL responders + // This is a workaround as somewhere down the chain the paste event gets eaten + while (nextResponder != nil) { + if let nextResponder = nextResponder { + if (nextResponder.responds(to: #selector(UIResponderStandardEditActions.paste(_:)))) { + nextResponder.perform(#selector(UIResponderStandardEditActions.paste(_:)), with: sender) + } } + nextResponder = nextResponder?.next; } - nextResponder = nextResponder?.next; - } + } // end if } } From ee9f0538e359c095ae2e5a4c0564f5995dcb9988 Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 1 Dec 2022 15:48:01 +0800 Subject: [PATCH 249/733] fix: timeline reload blink issue --- .../HomeTimelineViewModel+Diffable.swift | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index cabc655c9..29bff623b 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -41,7 +41,7 @@ extension HomeTimelineViewModel { guard let self = self else { return } guard let diffableDataSource = self.diffableDataSource else { return } self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): incoming \(records.count) objects") - Task { + Task { @MainActor in let start = CACurrentMediaTime() defer { let end = CACurrentMediaTime() @@ -98,22 +98,22 @@ extension HomeTimelineViewModel { self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): snapshot has changes") } - guard let difference = await self.calculateReloadSnapshotDifference( + guard let difference = self.calculateReloadSnapshotDifference( tableView: tableView, oldSnapshot: oldSnapshot, newSnapshot: newSnapshot ) else { - await self.updateSnapshotUsingReloadData(snapshot: newSnapshot) + self.updateSnapshotUsingReloadData(snapshot: newSnapshot) self.didLoadLatest.send() self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): applied new snapshot") return } - await self.updateSnapshotUsingReloadData(snapshot: newSnapshot) - await tableView.scrollToRow(at: difference.targetIndexPath, at: .top, animated: false) - var contentOffset = await tableView.contentOffset - contentOffset.y = await tableView.contentOffset.y - difference.sourceDistanceToTableViewTopEdge - await tableView.setContentOffset(contentOffset, animated: false) + self.updateSnapshotUsingReloadData(snapshot: newSnapshot) + tableView.scrollToRow(at: difference.targetIndexPath, at: .top, animated: false) + var contentOffset = tableView.contentOffset + contentOffset.y = tableView.contentOffset.y - difference.sourceDistanceToTableViewTopEdge + tableView.setContentOffset(contentOffset, animated: false) self.didLoadLatest.send() self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): applied new snapshot") } // end Task @@ -135,9 +135,9 @@ extension HomeTimelineViewModel { @MainActor func updateSnapshotUsingReloadData( snapshot: NSDiffableDataSourceSnapshot - ) async { + ) { if #available(iOS 15.0, *) { - await self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) + self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) } else { diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil) } From b7458dfc7b596d8fef819fe749c814095a95c722 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 22 Nov 2022 11:11:36 +0100 Subject: [PATCH 250/733] feat: Implement hashtag button on Profile --- .../Scene/Profile/ProfileViewController.swift | 26 ++ .../CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData 5.xcdatamodel/contents | 255 ++++++++++++++++++ .../Entity/Mastodon/Instance.swift | 10 +- .../Extension/CoreDataStack/Instance.swift | 7 + .../APIService+CoreData+Instance.swift | 5 +- .../Mastodon+API+Account+FollowedTags.swift | 73 +++++ .../Entity/Mastodon+Entity+Tag.swift | 6 +- 8 files changed, 376 insertions(+), 8 deletions(-) create mode 100644 MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents create mode 100644 MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index ffe8bcc83..62aa8e57a 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -104,6 +104,13 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.seeMore return barButtonItem }() + + private(set) lazy var followedTagsBarButtonItem: UIBarButtonItem = { + let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "number"), style: .plain, target: self, action: #selector(ProfileViewController.followedTagsItemPressed(_:))) + barButtonItem.tintColor = .white + //barButtonItem.accessibilityLabel = "" TODO: add missing L10n.Common.Controls.Actions.XXXXXX + return barButtonItem + }() let refreshControl: RefreshControl = { let refreshControl = RefreshControl() @@ -243,6 +250,11 @@ extension ProfileViewController { items.append(self.shareBarButtonItem) items.append(self.favoriteBarButtonItem) items.append(self.bookmarkBarButtonItem) + + if self.currentInstance?.canFollowTags == true { + items.append(self.followedTagsBarButtonItem) + } + return } @@ -545,6 +557,10 @@ extension ProfileViewController { ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } + + @objc private func followedTagsItemPressed(_ sender: UIBarButtonItem) { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } @objc private func refreshControlValueChanged(_ sender: RefreshControl) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) @@ -914,3 +930,13 @@ extension ProfileViewController: PagerTabStripNavigateable { } +private extension ProfileViewController { + var currentInstance: Instance? { + guard let authenticationRecord = authContext.mastodonAuthenticationBox + .authenticationRecord + .object(in: context.managedObjectContext) + else { return nil } + + return authenticationRecord.instance + } +} diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index 1d5ea989f..2145ac780 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 4.xcdatamodel + CoreData 5.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents new file mode 100644 index 000000000..69ffac191 --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift index 8976097ef..cc21e8351 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift @@ -10,7 +10,8 @@ import CoreData public final class Instance: NSManagedObject { @NSManaged public var domain: String - + @NSManaged public var version: String? + @NSManaged public private(set) var createdAt: Date @NSManaged public private(set) var updatedAt: Date @@ -35,6 +36,7 @@ extension Instance { ) -> Instance { let instance: Instance = context.insertObject() instance.domain = property.domain + instance.version = property.version return instance } @@ -50,9 +52,11 @@ extension Instance { extension Instance { public struct Property { public let domain: String - - public init(domain: String) { + public let version: String? + + public init(domain: String, version: String?) { self.domain = domain + self.version = version } } } diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift index 4192b68a2..7e925b665 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift @@ -23,3 +23,10 @@ extension Instance { return try? JSONEncoder().encode(configuration) } } + +extension Instance { + public var canFollowTags: Bool { + guard let majorVersionString = version?.split(separator: ".").first else { return false } + return Int(majorVersionString) == 4 // following Tags is support beginning with Mastodon v4.0.0 + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+Instance.swift b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+Instance.swift index 2127a2981..d9566f6d4 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+Instance.swift @@ -46,7 +46,7 @@ extension APIService.CoreData { } else { let instance = Instance.insert( into: managedObjectContext, - property: Instance.Property(domain: domain) + property: Instance.Property(domain: domain, version: entity.version) ) let configurationRaw = entity.configuration.flatMap { Instance.encode(configuration: $0) } instance.update(configurationRaw: configurationRaw) @@ -69,7 +69,8 @@ extension APIService.CoreData { let configurationRaw = entity.configuration.flatMap { Instance.encode(configuration: $0) } instance.update(configurationRaw: configurationRaw) - + instance.version = entity.version + instance.didUpdate(at: networkDate) } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift new file mode 100644 index 000000000..f1020180f --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift @@ -0,0 +1,73 @@ +// +// Mastodon+API+Account+FollowedTags.swift +// +// +// Created by Marcus Kida on 22.11.22. +// + +import Foundation +import Combine + +extension Mastodon.API.Account { + + static func followedTagsEndpointURL(domain: String) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("followed_tags") + } + + /// Followed Tags + /// + /// View your followed hashtags. + /// + /// - Since: 4.0.0 + /// - Version: 4.0.3 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/followed_tags/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - authorization: User token + /// - Returns: `AnyPublisher` contains `[Tag]` nested in the response + public static func followers( + session: URLSession, + domain: String, + query: FollowedTagsQuery, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: followedTagsEndpointURL(domain: domain), + query: query, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.Tag].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + public struct FollowedTagsQuery: Codable, GetQuery { + + public let limit: Int? // default 100 + + enum CodingKeys: String, CodingKey { + case limit + } + + public init( + limit: Int? + ) { + self.limit = limit + } + + var queryItems: [URLQueryItem]? { + var items: [URLQueryItem] = [] + limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) } + guard !items.isEmpty else { return nil } + return items + } + + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift index 84875359a..9c091d73f 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift @@ -11,9 +11,9 @@ extension Mastodon.Entity { /// Tag /// /// - Since: 0.9.0 - /// - Version: 3.3.0 + /// - Version: 4.0.0 /// # Last Update - /// 2021/1/28 + /// 2022/11/22 /// # Reference /// [Document](https://docs.joinmastodon.org/entities/tag/) public struct Tag: Hashable, Codable { @@ -23,11 +23,13 @@ extension Mastodon.Entity { public let url: String public let history: [History]? + public let following: Bool? enum CodingKeys: String, CodingKey { case name case url case history + case following } public static func == (lhs: Mastodon.Entity.Tag, rhs: Mastodon.Entity.Tag) -> Bool { From 2987bb29fabf9abe8b5059186a9f6e4a9db3f6d2 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 22 Nov 2022 14:15:41 +0100 Subject: [PATCH 251/733] feat: Add FollowedTagsViewController --- Mastodon.xcodeproj/project.pbxproj | 12 ++++++ .../FollowedTagsViewController.swift | 38 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0c43b71df..46d8bc2ea 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; }; 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; + 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; }; 2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; }; @@ -520,6 +521,7 @@ 0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; }; 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; + 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SFSymbols.swift"; sourceTree = ""; }; 2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; }; @@ -1226,6 +1228,14 @@ path = Pods; sourceTree = ""; }; + 2A506CF2292CD83B00059C37 /* FollowedTags */ = { + isa = PBXGroup; + children = ( + 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */, + ); + path = FollowedTags; + sourceTree = ""; + }; 2D152A8A25C295B8009AA50C /* Content */ = { isa = PBXGroup; children = ( @@ -2369,6 +2379,7 @@ DB9D6C0825E4F5A60051B173 /* Profile */ = { isa = PBXGroup; children = ( + 2A506CF2292CD83B00059C37 /* FollowedTags */, 62047EBE28874C8F00A3BA5D /* Bookmark */, DBB525462611ED57002F1F29 /* Header */, DBB525262611EBDA002F1F29 /* Paging */, @@ -3301,6 +3312,7 @@ DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */, 0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */, 5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */, + 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */, DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */, DB852D1926FAEB6B00FC9D81 /* SidebarViewController.swift in Sources */, 2D206B9225F60EA700143C56 /* UIControl.swift in Sources */, diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift new file mode 100644 index 000000000..2f705dcec --- /dev/null +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift @@ -0,0 +1,38 @@ +// +// FollowedTagsViewController.swift +// Mastodon +// +// Created by Marcus Kida on 22.11.22. +// + +import os +import UIKit +import Combine +import MastodonAsset +import MastodonCore +import MastodonUI +import MastodonLocalization + +final class FollowedTagsViewController: UIViewController, NeedsDependency { + let logger = Logger(subsystem: String(describing: FollowedTagsViewController.self), category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + var viewModel: BookmarkViewModel! + + lazy var tableView: UITableView = { + let tableView = UITableView() + tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self)) + tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) + tableView.rowHeight = UITableView.automaticDimension + tableView.separatorStyle = .none + tableView.backgroundColor = .clear + return tableView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } +} From 178a6e503a7d7b5f668341083aea4b31dfa879b7 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 23 Nov 2022 15:57:51 +0100 Subject: [PATCH 252/733] feat: Implement layout for hashtag timeline header view --- Mastodon.xcodeproj/project.pbxproj | 4 + .../HashtagTimelineHeaderView.swift | 109 ++++++++++++++++++ .../HashtagTimelineViewController.swift | 29 +++++ .../HashtagTimelineViewModel.swift | 18 ++- .../Service/API/APIService+Account.swift | 37 ++++++ .../Service/API/APIService+Tags.swift | 49 ++++++++ .../Mastodon+API+Account+FollowedTags.swift | 2 +- .../MastodonSDK/API/Mastodon+API+Tags.swift | 49 ++++++++ .../MastodonSDK/API/Mastodon+API.swift | 1 + 9 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift create mode 100644 MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 46d8bc2ea..2102647ec 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; + 2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; }; 2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; }; @@ -522,6 +523,7 @@ 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; + 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderView.swift; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SFSymbols.swift"; sourceTree = ""; }; 2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; }; @@ -1126,6 +1128,7 @@ 0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */, 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */, 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */, + 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */, ); path = HashtagTimeline; sourceTree = ""; @@ -3301,6 +3304,7 @@ 2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */, DB025B78278D606A002F581E /* StatusItem.swift in Sources */, DB697DD4278F4927004EF2F7 /* StatusTableViewCellDelegate.swift in Sources */, + 2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */, DBA5E7A5263BD28C004598BB /* ContextMenuImagePreviewViewModel.swift in Sources */, DB3E6FF52807C40300B035AE /* DiscoveryForYouViewController.swift in Sources */, 2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */, diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift new file mode 100644 index 000000000..80a6795f3 --- /dev/null +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -0,0 +1,109 @@ +// +// HashtagTimelineHeaderView.swift +// Mastodon +// +// Created by Marcus Kida on 22.11.22. +// + +import UIKit +import MastodonSDK +import MastodonUI + +fileprivate extension CGFloat { + static let padding: CGFloat = 16 + static let descriptionLabelSpacing: CGFloat = 12 +} + +final class HashtagTimelineHeaderView: UIView { + let titleLabel = UILabel() + + let postCountLabel = UILabel() + let participantsLabel = UILabel() + let postsTodayLabel = UILabel() + + let postCountDescLabel = UILabel() + let participantsDescLabel = UILabel() + let postsTodayDescLabel = UILabel() + + let followButton: UIButton = { + let button = RoundedEdgesButton(type: .custom) + button.cornerRadius = 10 + button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 16, bottom: 5, right: 16) // set 28pt height + button.titleLabel?.font = .systemFont(ofSize: 14, weight: .bold) + button.backgroundColor = .black + return button + }() + + init() { + super.init(frame: .zero) + setupLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +private extension HashtagTimelineHeaderView { + func setupLayout() { + [titleLabel, postCountLabel, participantsLabel, postsTodayLabel, postCountDescLabel, participantsDescLabel, postsTodayDescLabel, followButton].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + addSubview($0) + } + + // hashtag name / title + titleLabel.font = UIFontMetrics(forTextStyle: .title2).scaledFont(for: .systemFont(ofSize: 22, weight: .bold)) + + [postCountLabel, participantsLabel, postsTodayLabel].forEach { + $0.font = UIFontMetrics(forTextStyle: .title3).scaledFont(for: .systemFont(ofSize: 20, weight: .bold)) + $0.text = "999" + } + + [postCountDescLabel, participantsDescLabel, postsTodayDescLabel].forEach { + $0.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) + } + + postCountDescLabel.text = "posts" + participantsDescLabel.text = "participants" + postsTodayDescLabel.text = "posts today" + + NSLayoutConstraint.activate([ + titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: .padding), + titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: .padding), + titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -CGFloat.padding), + + postCountLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: .padding), + postCountLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), + postCountDescLabel.leadingAnchor.constraint(equalTo: postCountLabel.leadingAnchor), + + participantsDescLabel.leadingAnchor.constraint(equalTo: postCountDescLabel.trailingAnchor, constant: .descriptionLabelSpacing), + participantsLabel.centerXAnchor.constraint(equalTo: participantsDescLabel.centerXAnchor), + participantsLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: .padding), + + postsTodayDescLabel.leadingAnchor.constraint(equalTo: participantsDescLabel.trailingAnchor, constant: .descriptionLabelSpacing), + postsTodayLabel.centerXAnchor.constraint(equalTo: postsTodayDescLabel.centerXAnchor), + postsTodayLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: .padding), + + postCountDescLabel.topAnchor.constraint(equalTo: postCountLabel.bottomAnchor), + participantsDescLabel.topAnchor.constraint(equalTo: participantsLabel.bottomAnchor), + postsTodayDescLabel.topAnchor.constraint(equalTo: postsTodayLabel.bottomAnchor), + + postCountDescLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -CGFloat.padding), + participantsDescLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -CGFloat.padding), + postsTodayDescLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -CGFloat.padding), + + followButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -CGFloat.padding), + followButton.bottomAnchor.constraint(equalTo: postsTodayDescLabel.bottomAnchor), + followButton.topAnchor.constraint(equalTo: postsTodayLabel.topAnchor), + followButton.widthAnchor.constraint(equalToConstant: 84) + ]) + } +} + +extension HashtagTimelineHeaderView { + func update(_ entity: Mastodon.Entity.Tag) { + titleLabel.text = "#\(entity.name)" + followButton.setTitle(entity.following == true ? "Unfollow" : "Follow", for: .normal) + } +} diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 4a0be3816..d48220615 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -15,6 +15,7 @@ import MastodonAsset import MastodonCore import MastodonUI import MastodonLocalization +import MastodonSDK final class HashtagTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { @@ -27,6 +28,18 @@ final class HashtagTimelineViewController: UIViewController, NeedsDependency, Me var disposeBag = Set() var viewModel: HashtagTimelineViewModel! + + private lazy var headerView: HashtagTimelineHeaderView = { + let headerView = HashtagTimelineHeaderView() + headerView.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + headerView.heightAnchor.constraint(equalToConstant: 118), +// headerView.widthAnchor.constraint(equalTo: tableView.widthAnchor) + ]) + + return headerView + }() let composeBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() @@ -114,6 +127,14 @@ extension HashtagTimelineViewController { self?.updatePromptTitle() } .store(in: &disposeBag) + + viewModel.hashtagDetails + .receive(on: DispatchQueue.main) + .sink { [weak self] tag in + guard let tag = tag else { return } + self?.updateHeaderView(with: tag) + } + .store(in: &disposeBag) } override func viewWillAppear(_ animated: Bool) { @@ -148,7 +169,15 @@ extension HashtagTimelineViewController { subtitle = L10n.Plural.peopleTalking(peopleTalkingNumber) } } +} +extension HashtagTimelineViewController { + private func updateHeaderView(with tag: Mastodon.Entity.Tag) { + if tableView.tableHeaderView == nil { + tableView.tableHeaderView = headerView + } + headerView.update(tag) + } } extension HashtagTimelineViewController { diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift index af4d2a01a..86ae80704 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift @@ -23,7 +23,7 @@ final class HashtagTimelineViewModel { var disposeBag = Set() var needLoadMiddleIndex: Int? = nil - + // input let context: AppContext let authContext: AuthContext @@ -32,10 +32,11 @@ final class HashtagTimelineViewModel { let timelinePredicate = CurrentValueSubject(nil) let hashtagEntity = CurrentValueSubject(nil) let listBatchFetchViewModel = ListBatchFetchViewModel() - + // output var diffableDataSource: UITableViewDiffableDataSource? let didLoadLatest = PassthroughSubject() + let hashtagDetails = CurrentValueSubject(nil) // bottom loader private(set) lazy var stateMachine: GKStateMachine = { @@ -61,6 +62,7 @@ final class HashtagTimelineViewModel { domain: authContext.mastodonAuthenticationBox.domain, additionalTweetPredicate: nil ) + updateTagInformation() // end init } @@ -70,3 +72,15 @@ final class HashtagTimelineViewModel { } +private extension HashtagTimelineViewModel { + func updateTagInformation() { + Task { @MainActor in + let tag = try? await context.apiService.getTagInformation( + for: hashtag, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + self.hashtagDetails.send(tag) + } + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift index 1b6a57a83..c27f8cf67 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift @@ -161,3 +161,40 @@ extension APIService { } } + +extension APIService { + public func getFollowedTags( + domain: String, + query: Mastodon.API.Account.FollowedTagsQuery, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Tag]> { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Account.followedTags( + session: session, + domain: domain, + query: query, + authorization: authorization + ).singleOutput() + + let managedObjectContext = self.backgroundManagedObjectContext + try await managedObjectContext.performChanges { + let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user + + for entity in response.value { + _ = Persistence.Tag.createOrMerge( + in: managedObjectContext, + context: Persistence.Tag.PersistContext( + domain: domain, + entity: entity, + me: me, + networkDate: response.networkDate + ) + ) + } + } + + return response + } // end func +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift new file mode 100644 index 000000000..80e0d083f --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift @@ -0,0 +1,49 @@ +// +// APIService+Tags.swift +// +// +// Created by Marcus Kida on 23.11.22. +// + +import os.log +import Foundation +import Combine +import CoreData +import CoreDataStack +import MastodonSDK + +extension APIService { + + public func getTagInformation( + for tag: String, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Tags.tag( + session: session, + domain: domain, + tagId: tag, + authorization: authorization + ).singleOutput() + + let managedObjectContext = self.backgroundManagedObjectContext + try await managedObjectContext.performChanges { + let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user + + _ = Persistence.Tag.createOrMerge( + in: managedObjectContext, + context: Persistence.Tag.PersistContext( + domain: domain, + entity: response.value, + me: me, + networkDate: response.networkDate + ) + ) + } + + return response + } // end func + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift index f1020180f..02c79e35b 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FollowedTags.swift @@ -28,7 +28,7 @@ extension Mastodon.API.Account { /// - domain: Mastodon instance domain. e.g. "example.com" /// - authorization: User token /// - Returns: `AnyPublisher` contains `[Tag]` nested in the response - public static func followers( + public static func followedTags( session: URLSession, domain: String, query: FollowedTagsQuery, diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift new file mode 100644 index 000000000..d8c8f6354 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift @@ -0,0 +1,49 @@ +// +// Mastodin+API+Tags.swift +// +// +// Created by Marcus Kida on 23.11.22. +// + +import Combine +import Foundation + +extension Mastodon.API.Tags { + static func tagsEndpointURL(domain: String) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("tags") + } + + /// Followed Tags + /// + /// View your followed hashtags. + /// + /// - Since: 4.0.0 + /// - Version: 4.0.3 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/tags/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - authorization: User token + /// - tagId: The Hashtag + /// - Returns: `AnyPublisher` contains `Tag` nested in the response + public static func tag( + session: URLSession, + domain: String, + tagId: String, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: tagsEndpointURL(domain: domain).appendingPathComponent(tagId), + query: nil, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Tag.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index 5d507bace..a1eb47873 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -112,6 +112,7 @@ extension Mastodon.API { public enum Polls { } public enum Reblog { } public enum Statuses { } + public enum Tags {} public enum Timeline { } public enum Trends { } public enum Suggestions { } From 9d245d3205293a2a22275055babc6532cc8c41d8 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 23 Nov 2022 17:24:25 +0100 Subject: [PATCH 253/733] feat: Fix follow hashtags header layout --- .../HashtagTimeline/HashtagTimelineHeaderView.swift | 12 +++++++++++- .../HashtagTimelineViewController.swift | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 80a6795f3..49442c03d 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -25,6 +25,8 @@ final class HashtagTimelineHeaderView: UIView { let participantsDescLabel = UILabel() let postsTodayDescLabel = UILabel() + private var widthConstraint: NSLayoutConstraint! + let followButton: UIButton = { let button = RoundedEdgesButton(type: .custom) button.cornerRadius = 10 @@ -67,8 +69,12 @@ private extension HashtagTimelineHeaderView { postCountDescLabel.text = "posts" participantsDescLabel.text = "participants" postsTodayDescLabel.text = "posts today" - + + widthConstraint = widthAnchor.constraint(equalToConstant: 0) + NSLayoutConstraint.activate([ + widthConstraint, + titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: .padding), titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: .padding), titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -CGFloat.padding), @@ -106,4 +112,8 @@ extension HashtagTimelineHeaderView { titleLabel.text = "#\(entity.name)" followButton.setTitle(entity.following == true ? "Unfollow" : "Follow", for: .normal) } + + func updateWidthConstraint(_ constant: CGFloat) { + widthConstraint.constant = constant + } } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index d48220615..8d79b0ed1 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -178,6 +178,11 @@ extension HashtagTimelineViewController { } headerView.update(tag) } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + headerView.updateWidthConstraint(tableView.bounds.width) + } } extension HashtagTimelineViewController { From b020f566f47012e9e87edb48537e767d32129700 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 23 Nov 2022 17:54:53 +0100 Subject: [PATCH 254/733] feat: Implement real numbers of HashtagTimelineHeader --- .../HashtagTimelineHeaderView.swift | 27 +++++++++++-- .../Button/tagFollow.colorset/Contents.json | 38 +++++++++++++++++++ .../Button/tagUnfollow.colorset/Contents.json | 38 +++++++++++++++++++ .../MastodonAsset/Generated/Assets.swift | 2 + 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 49442c03d..996c18ffb 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -8,6 +8,7 @@ import UIKit import MastodonSDK import MastodonUI +import MastodonAsset fileprivate extension CGFloat { static let padding: CGFloat = 16 @@ -32,7 +33,6 @@ final class HashtagTimelineHeaderView: UIView { button.cornerRadius = 10 button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 16, bottom: 5, right: 16) // set 28pt height button.titleLabel?.font = .systemFont(ofSize: 14, weight: .bold) - button.backgroundColor = .black return button }() @@ -101,8 +101,7 @@ private extension HashtagTimelineHeaderView { followButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -CGFloat.padding), followButton.bottomAnchor.constraint(equalTo: postsTodayDescLabel.bottomAnchor), - followButton.topAnchor.constraint(equalTo: postsTodayLabel.topAnchor), - followButton.widthAnchor.constraint(equalToConstant: 84) + followButton.topAnchor.constraint(equalTo: postsTodayLabel.topAnchor) ]) } } @@ -111,6 +110,28 @@ extension HashtagTimelineHeaderView { func update(_ entity: Mastodon.Entity.Tag) { titleLabel.text = "#\(entity.name)" followButton.setTitle(entity.following == true ? "Unfollow" : "Follow", for: .normal) + + followButton.backgroundColor = entity.following == true ? Asset.Colors.Button.tagUnfollow.color : Asset.Colors.Button.tagFollow.color + followButton.setTitleColor( + entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, + for: .normal + ) + + if let history = entity.history { + postCountLabel.text = String( + history.reduce(0) { res, acc in + res + (Int(acc.uses) ?? 0) + } + ) + + participantsLabel.text = String( + history.reduce(0) { res, acc in + res + (Int(acc.accounts) ?? 0) + } + ) + + postsTodayLabel.text = history.first?.uses + } } func updateWidthConstraint(_ constant: CGFloat) { diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json new file mode 100644 index 000000000..9bc42278d --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x38", + "green" : "0x29", + "red" : "0x2B" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.700", + "blue" : "0x38", + "green" : "0x29", + "red" : "0x2B" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json new file mode 100644 index 000000000..2790f171d --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.250", + "blue" : "0x38", + "green" : "0x29", + "red" : "0x2B" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift index 155227685..607fe4390 100644 --- a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift +++ b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift @@ -49,6 +49,8 @@ public enum Asset { public static let actionToolbar = ColorAsset(name: "Colors/Button/action.toolbar") public static let disabled = ColorAsset(name: "Colors/Button/disabled") public static let inactive = ColorAsset(name: "Colors/Button/inactive") + public static let tagFollow = ColorAsset(name: "Colors/Button/tagFollow") + public static let tagUnfollow = ColorAsset(name: "Colors/Button/tagUnfollow") } public enum Icon { public static let plus = ColorAsset(name: "Colors/Icon/plus") From b9e4c69576dd112bc237546ee6c97a3955f13915 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 23 Nov 2022 22:38:25 +0100 Subject: [PATCH 255/733] feat: Implement follow/unfollow tag functionality --- .../HashtagTimelineHeaderView.swift | 10 ++- .../HashtagTimelineViewController.swift | 10 +++ .../HashtagTimelineViewModel.swift | 24 ++++++ .../Service/API/APIService+Tags.swift | 49 +++++++++++- .../MastodonSDK/API/Mastodon+API+Tags.swift | 74 ++++++++++++++++++- .../Entity/Mastodon+Entity+Tag.swift | 4 + 6 files changed, 163 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 996c18ffb..2ef1ea95c 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -28,6 +28,8 @@ final class HashtagTimelineHeaderView: UIView { private var widthConstraint: NSLayoutConstraint! + var onButtonTapped: (() -> Void)? + let followButton: UIButton = { let button = RoundedEdgesButton(type: .custom) button.cornerRadius = 10 @@ -69,7 +71,11 @@ private extension HashtagTimelineHeaderView { postCountDescLabel.text = "posts" participantsDescLabel.text = "participants" postsTodayDescLabel.text = "posts today" - + + followButton.addAction(UIAction(handler: { [weak self] _ in + self?.onButtonTapped?() + }), for: .touchUpInside) + widthConstraint = widthAnchor.constraint(equalToConstant: 0) NSLayoutConstraint.activate([ @@ -133,7 +139,7 @@ extension HashtagTimelineHeaderView { postsTodayLabel.text = history.first?.uses } } - + func updateWidthConstraint(_ constant: CGFloat) { widthConstraint.constant = constant } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 8d79b0ed1..698966821 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -177,6 +177,16 @@ extension HashtagTimelineViewController { tableView.tableHeaderView = headerView } headerView.update(tag) + headerView.onButtonTapped = { [weak self] in + switch tag.following { + case .some(false): + self?.viewModel.followTag() + case .some(true): + self?.viewModel.unfollowTag() + default: + break + } + } } override func viewDidLayoutSubviews() { diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift index 86ae80704..f4e7ef428 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift @@ -72,6 +72,30 @@ final class HashtagTimelineViewModel { } +extension HashtagTimelineViewModel { + func followTag() { + self.hashtagDetails.send(hashtagDetails.value?.copy(following: true)) + Task { @MainActor in + let tag = try? await context.apiService.followTag( + for: hashtag, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + self.hashtagDetails.send(tag) + } + } + + func unfollowTag() { + self.hashtagDetails.send(hashtagDetails.value?.copy(following: false)) + Task { @MainActor in + let tag = try? await context.apiService.unfollowTag( + for: hashtag, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + self.hashtagDetails.send(tag) + } + } +} + private extension HashtagTimelineViewModel { func updateTagInformation() { Task { @MainActor in diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift index 80e0d083f..0b0320078 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Tags.swift @@ -21,13 +21,57 @@ extension APIService { let domain = authenticationBox.domain let authorization = authenticationBox.userAuthorization - let response = try await Mastodon.API.Tags.tag( + let response = try await Mastodon.API.Tags.getTagInformation( session: session, domain: domain, tagId: tag, authorization: authorization ).singleOutput() + return try await persistTag(from: response, domain: domain, authenticationBox: authenticationBox) + } // end func + + public func followTag( + for tag: String, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Tags.followTag( + session: session, + domain: domain, + tagId: tag, + authorization: authorization + ).singleOutput() + + return try await persistTag(from: response, domain: domain, authenticationBox: authenticationBox) + } // end func + + public func unfollowTag( + for tag: String, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Tags.unfollowTag( + session: session, + domain: domain, + tagId: tag, + authorization: authorization + ).singleOutput() + + return try await persistTag(from: response, domain: domain, authenticationBox: authenticationBox) + } // end func +} + +fileprivate extension APIService { + func persistTag( + from response: Mastodon.Response.Content, + domain: String, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { let managedObjectContext = self.backgroundManagedObjectContext try await managedObjectContext.performChanges { let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user @@ -44,6 +88,5 @@ extension APIService { } return response - } // end func - + } } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift index d8c8f6354..42f8b4fd3 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Tags.swift @@ -14,9 +14,9 @@ extension Mastodon.API.Tags { .appendingPathComponent("tags") } - /// Followed Tags + /// Tags /// - /// View your followed hashtags. + /// View information about a single tag. /// /// - Since: 4.0.0 /// - Version: 4.0.3 @@ -28,7 +28,7 @@ extension Mastodon.API.Tags { /// - authorization: User token /// - tagId: The Hashtag /// - Returns: `AnyPublisher` contains `Tag` nested in the response - public static func tag( + public static func getTagInformation( session: URLSession, domain: String, tagId: String, @@ -46,4 +46,72 @@ extension Mastodon.API.Tags { } .eraseToAnyPublisher() } + + /// Tags + /// + /// Follow a hashtag. + /// + /// - Since: 4.0.0 + /// - Version: 4.0.3 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/tags/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - authorization: User token + /// - tagId: The Hashtag + /// - Returns: `AnyPublisher` contains `Tag` nested in the response + public static func followTag( + session: URLSession, + domain: String, + tagId: String, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.post( + url: tagsEndpointURL(domain: domain).appendingPathComponent(tagId) + .appendingPathComponent("follow"), + query: nil, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Tag.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + /// Tags + /// + /// Unfollow a hashtag. + /// + /// - Since: 4.0.0 + /// - Version: 4.0.3 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/tags/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - authorization: User token + /// - tagId: The Hashtag + /// - Returns: `AnyPublisher` contains `Tag` nested in the response + public static func unfollowTag( + session: URLSession, + domain: String, + tagId: String, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.post( + url: tagsEndpointURL(domain: domain).appendingPathComponent(tagId) + .appendingPathComponent("unfollow"), + query: nil, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Tag.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } } diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift index 9c091d73f..d40bf8915 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift @@ -41,5 +41,9 @@ extension Mastodon.Entity { hasher.combine(name) hasher.combine(url) } + + public func copy(following: Bool?) -> Self { + Tag(name: name, url: url, history: history, following: following) + } } } From 855d2cbacd06d18f0ba0bc8f69f9e43dbdab98f7 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 13:07:28 +0100 Subject: [PATCH 256/733] feat: Implement followed tags overview --- Mastodon.xcodeproj/project.pbxproj | 12 ++ Mastodon/Coordinator/SceneCoordinator.swift | 5 + .../HashtagTimelineHeaderView.swift | 61 ++++++--- ...ashtagTimelineHeaderViewActionButton.swift | 38 ++++++ .../HashtagTimelineViewController.swift | 3 +- .../FollowedTagsTableViewCell.swift | 76 +++++++++++ .../FollowedTagsViewController.swift | 33 ++++- .../FollowedTags/FollowedTagsViewModel.swift | 120 ++++++++++++++++++ .../Scene/Profile/ProfileViewController.swift | 3 + .../CoreData 5.xcdatamodel/contents | 3 + .../Entity/Mastodon/MastodonUser.swift | 1 + .../CoreDataStack/Entity/Mastodon/Tag.swift | 43 ++++++- .../CoreDataStack/Tag+Property.swift | 1 + .../FollowedTagsFetchedResultController.swift | 90 +++++++++++++ .../Persistence/Persistence+Tag.swift | 7 + .../Service/API/APIService+Account.swift | 1 + 16 files changed, 473 insertions(+), 24 deletions(-) create mode 100644 Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift create mode 100644 Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift create mode 100644 Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift create mode 100644 MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 2102647ec..e94871b4d 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -23,8 +23,11 @@ 0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; }; 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; + 2A3F6FE3292ECB5E002E6DA7 /* FollowedTagsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */; }; + 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; }; 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; 2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */; }; + 2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; }; 2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; }; @@ -522,8 +525,11 @@ 0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; }; 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; + 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewModel.swift; sourceTree = ""; }; + 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = ""; }; 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderView.swift; sourceTree = ""; }; + 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderViewActionButton.swift; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SFSymbols.swift"; sourceTree = ""; }; 2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; }; @@ -1129,6 +1135,7 @@ 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */, 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */, 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */, + 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */, ); path = HashtagTimeline; sourceTree = ""; @@ -1235,6 +1242,8 @@ isa = PBXGroup; children = ( 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */, + 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */, + 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */, ); path = FollowedTags; sourceTree = ""; @@ -3480,6 +3489,7 @@ DBCC3B30261440A50045B23D /* UITabBarController.swift in Sources */, DB3E6FE42806A5B800B035AE /* DiscoverySection.swift in Sources */, DB8190C62601FF0400020C08 /* AttachmentContainerView.swift in Sources */, + 2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */, DB697DDB278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift in Sources */, DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */, DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */, @@ -3488,6 +3498,7 @@ DB67D08627312E67006A36CF /* WizardViewController.swift in Sources */, DB6746EB278ED8B0008A6B94 /* PollOptionView+Configuration.swift in Sources */, DB0F9D54283EB3C000379AF8 /* ProfileHeaderView+ViewModel.swift in Sources */, + 2A3F6FE3292ECB5E002E6DA7 /* FollowedTagsViewModel.swift in Sources */, DBFEEC99279BDCDE004F81DD /* ProfileAboutViewModel.swift in Sources */, 2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */, DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */, @@ -3518,6 +3529,7 @@ 5BB04FF5262F0E6D0043BFF6 /* ReportSection.swift in Sources */, DBEFCD82282A2AB100C0ABEA /* ReportServerRulesView.swift in Sources */, DBA94436265CBB7400C537E1 /* ProfileFieldItem.swift in Sources */, + 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */, C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */, DB023D2A27A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift in Sources */, DB98EB6027B10E150082E365 /* ReportCommentTableViewCell.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index c3019010a..3dc73c020 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -173,6 +173,7 @@ extension SceneCoordinator { case rebloggedBy(viewModel: UserListViewModel) case favoritedBy(viewModel: UserListViewModel) case bookmark(viewModel: BookmarkViewModel) + case followedTags(viewModel: FollowedTagsViewModel) // setting case settings(viewModel: SettingsViewModel) @@ -448,6 +449,10 @@ private extension SceneCoordinator { let _viewController = BookmarkViewController() _viewController.viewModel = viewModel viewController = _viewController + case .followedTags(let viewModel): + let _viewController = FollowedTagsViewController() + _viewController.viewModel = viewModel + viewController = _viewController case .favorite(let viewModel): let _viewController = FavoriteViewController() _viewController.viewModel = viewModel diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 2ef1ea95c..e8cc48e8f 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -6,6 +6,7 @@ // import UIKit +import CoreDataStack import MastodonSDK import MastodonUI import MastodonAsset @@ -16,6 +17,42 @@ fileprivate extension CGFloat { } final class HashtagTimelineHeaderView: UIView { + struct Data { + let name: String + let following: Bool + let postCount: Int + let participantsCount: Int + let postsTodayCount: Int + + static func from(_ entity: Mastodon.Entity.Tag) -> Self { + Data( + name: entity.name, + following: entity.following == true, + postCount: (entity.history ?? []).reduce(0) { res, acc in + res + (Int(acc.uses) ?? 0) + }, + participantsCount: (entity.history ?? []).reduce(0) { res, acc in + res + (Int(acc.accounts) ?? 0) + }, + postsTodayCount: Int(entity.history?.first?.uses ?? "0") ?? 0 + ) + } + + static func from(_ entity: Tag) -> Self { + Data( + name: entity.name, + following: entity.following, + postCount: entity.histories.reduce(0) { res, acc in + res + (Int(acc.uses) ?? 0) + }, + participantsCount: entity.histories.reduce(0) { res, acc in + res + (Int(acc.accounts) ?? 0) + }, + postsTodayCount: Int(entity.histories.first?.uses ?? "0") ?? 0 + ) + } + } + let titleLabel = UILabel() let postCountLabel = UILabel() @@ -31,7 +68,7 @@ final class HashtagTimelineHeaderView: UIView { var onButtonTapped: (() -> Void)? let followButton: UIButton = { - let button = RoundedEdgesButton(type: .custom) + let button = HashtagTimelineHeaderViewActionButton() button.cornerRadius = 10 button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 16, bottom: 5, right: 16) // set 28pt height button.titleLabel?.font = .systemFont(ofSize: 14, weight: .bold) @@ -76,7 +113,7 @@ private extension HashtagTimelineHeaderView { self?.onButtonTapped?() }), for: .touchUpInside) - widthConstraint = widthAnchor.constraint(equalToConstant: 0) + widthConstraint = widthAnchor.constraint(greaterThanOrEqualToConstant: 0) NSLayoutConstraint.activate([ widthConstraint, @@ -113,7 +150,7 @@ private extension HashtagTimelineHeaderView { } extension HashtagTimelineHeaderView { - func update(_ entity: Mastodon.Entity.Tag) { + func update(_ entity: HashtagTimelineHeaderView.Data) { titleLabel.text = "#\(entity.name)" followButton.setTitle(entity.following == true ? "Unfollow" : "Follow", for: .normal) @@ -123,21 +160,9 @@ extension HashtagTimelineHeaderView { for: .normal ) - if let history = entity.history { - postCountLabel.text = String( - history.reduce(0) { res, acc in - res + (Int(acc.uses) ?? 0) - } - ) - - participantsLabel.text = String( - history.reduce(0) { res, acc in - res + (Int(acc.accounts) ?? 0) - } - ) - - postsTodayLabel.text = history.first?.uses - } + postCountLabel.text = String(entity.postCount) + participantsLabel.text = String(entity.participantsCount) + postsTodayLabel.text = String(entity.postsTodayCount) } func updateWidthConstraint(_ constant: CGFloat) { diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift new file mode 100644 index 000000000..aff97b21c --- /dev/null +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift @@ -0,0 +1,38 @@ +// +// HashtagTimelineHeaderViewActionButton.swift +// Mastodon +// +// Created by Marcus Kida on 25.11.22. +// + +import UIKit +import MastodonUI +import MastodonAsset + +class HashtagTimelineHeaderViewActionButton: RoundedEdgesButton { + + init() { + super.init(frame: .zero) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func layoutSubviews() { + super.layoutSubviews() + + layer.setupShadow( + color: .lightGray, + alpha: 1, + x: 0, + y: 1, + blur: 2, + spread: 0, + roundedRect: bounds, + byRoundingCorners: .allCorners, + cornerRadii: CGSize(width: cornerRadius, height: cornerRadius) + ) + } +} + diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 698966821..380098559 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -35,7 +35,6 @@ final class HashtagTimelineViewController: UIViewController, NeedsDependency, Me NSLayoutConstraint.activate([ headerView.heightAnchor.constraint(equalToConstant: 118), -// headerView.widthAnchor.constraint(equalTo: tableView.widthAnchor) ]) return headerView @@ -176,7 +175,7 @@ extension HashtagTimelineViewController { if tableView.tableHeaderView == nil { tableView.tableHeaderView = headerView } - headerView.update(tag) + headerView.update(HashtagTimelineHeaderView.Data.from(tag)) headerView.onButtonTapped = { [weak self] in switch tag.following { case .some(false): diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift new file mode 100644 index 000000000..47c856313 --- /dev/null +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift @@ -0,0 +1,76 @@ +// +// FollowedTagsTableViewCell.swift +// Mastodon +// +// Created by Marcus Kida on 24.11.22. +// + +import UIKit +import CoreDataStack + +final class FollowedTagsTableViewCell: UITableViewCell { + private var hashtagView: HashtagTimelineHeaderView! + private let separatorLine = UIView.separatorLine + private weak var viewModel: FollowedTagsViewModel? + private weak var hashtag: Tag? + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setup() + } + + required init?(coder: NSCoder) { + fatalError("Not implemented") + } + + override func prepareForReuse() { + viewModel = nil + hashtagView = HashtagTimelineHeaderView() + super.prepareForReuse() + } +} + +private extension FollowedTagsTableViewCell { + func setup() { + selectionStyle = .none + + hashtagView = HashtagTimelineHeaderView() + hashtagView.translatesAutoresizingMaskIntoConstraints = false + + contentView.addSubview(hashtagView) + contentView.backgroundColor = .clear + + NSLayoutConstraint.activate([ + hashtagView.heightAnchor.constraint(equalToConstant: 118).priority(.required), + hashtagView.topAnchor.constraint(equalTo: contentView.topAnchor), + hashtagView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + hashtagView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + hashtagView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), + ]) + + separatorLine.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(separatorLine) + NSLayoutConstraint.activate([ + separatorLine.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + separatorLine.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), + separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)), + ]) + + hashtagView.onButtonTapped = { [weak self] in + guard let self = self, let tag = self.hashtag else { return } + self.viewModel?.followOrUnfollow(tag) + } + } +} + +extension FollowedTagsTableViewCell { + func populate(with tag: Tag) { + self.hashtag = tag + hashtagView.update(HashtagTimelineHeaderView.Data.from(tag)) + } + + func setup(_ viewModel: FollowedTagsViewModel) { + self.viewModel = viewModel + } +} diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift index 2f705dcec..0234c638c 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift @@ -20,12 +20,13 @@ final class FollowedTagsViewController: UIViewController, NeedsDependency { weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var disposeBag = Set() - var viewModel: BookmarkViewModel! + var viewModel: FollowedTagsViewModel! + let titleView = DoubleTitleLabelNavigationBarTitleView() + lazy var tableView: UITableView = { let tableView = UITableView() - tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self)) - tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) + tableView.register(FollowedTagsTableViewCell.self, forCellReuseIdentifier: String(describing: FollowedTagsTableViewCell.self)) tableView.rowHeight = UITableView.automaticDimension tableView.separatorStyle = .none tableView.backgroundColor = .clear @@ -36,3 +37,29 @@ final class FollowedTagsViewController: UIViewController, NeedsDependency { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) } } + +extension FollowedTagsViewController { + override func viewDidLoad() { + super.viewDidLoad() + + let _title = "Followed Tags" + title = _title + titleView.update(title: _title, subtitle: nil) + + navigationItem.titleView = titleView + + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor + ThemeService.shared.currentTheme + .receive(on: RunLoop.main) + .sink { [weak self] theme in + guard let self = self else { return } + self.view.backgroundColor = theme.secondarySystemBackgroundColor + } + .store(in: &disposeBag) + + tableView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(tableView) + tableView.pinToParent() + viewModel.setupTableView(tableView) + } +} diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift new file mode 100644 index 000000000..ee3a474b8 --- /dev/null +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift @@ -0,0 +1,120 @@ +// +// FollowedTagsViewModel.swift +// Mastodon +// +// Created by Marcus Kida on 23.11.22. +// + +import os +import UIKit +import Combine +import CoreData +import CoreDataStack +import MastodonSDK +import MastodonCore + +final class FollowedTagsViewModel: NSObject { + let logger = Logger(subsystem: String(describing: FollowedTagsViewModel.self), category: "ViewModel") + var disposeBag = Set() + let fetchedResultsController: FollowedTagsFetchedResultController + + private weak var tableView: UITableView? + + // input + let context: AppContext + let authContext: AuthContext + + init(context: AppContext, authContext: AuthContext) { + self.context = context + self.authContext = authContext + self.fetchedResultsController = FollowedTagsFetchedResultController( + managedObjectContext: context.managedObjectContext, + domain: authContext.mastodonAuthenticationBox.domain, + user: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)!.user + ) + super.init() + self.fetchedResultsController + .$records + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + self?.tableView?.reloadSections(IndexSet(integer: 0), with: .automatic) + } + .store(in: &disposeBag) + } +} + +extension FollowedTagsViewModel { + func setupTableView(_ tableView: UITableView) { + self.tableView = tableView + tableView.dataSource = self + tableView.delegate = self + + fetchFollowedTags { + tableView.reloadData() + } + } + + func fetchFollowedTags(_ done: @escaping () -> Void) { + Task { @MainActor [weak self] in + try? await self?._fetchFollowedTags() + done() + } + } + + private func _fetchFollowedTags() async throws { + try await context.apiService.getFollowedTags( + domain: authContext.mastodonAuthenticationBox.domain, + query: Mastodon.API.Account.FollowedTagsQuery(limit: nil), + authenticationBox: authContext.mastodonAuthenticationBox + ) + } + + func followOrUnfollow(_ tag: Tag) { + Task { @MainActor in + switch tag.following { + case true: + _ = try? await context.apiService.unfollowTag( + for: tag.name, + authenticationBox: authContext.mastodonAuthenticationBox + ) + case false: + _ = try? await context.apiService.followTag( + for: tag.name, + authenticationBox: authContext.mastodonAuthenticationBox + ) + } + try? await _fetchFollowedTags() + } + } +} + +extension FollowedTagsViewModel: UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + fetchedResultsController.records.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard + indexPath.section == 0, + let object = fetchedResultsController.records[indexPath.row].object(in: context.managedObjectContext) + else { + return UITableViewCell() + } + + let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: FollowedTagsTableViewCell.self), for: indexPath) as! FollowedTagsTableViewCell + + cell.setup(self) + cell.populate(with: object) + return cell + } +} + +extension FollowedTagsViewModel: UITableViewDelegate { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + } +} diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 62aa8e57a..13012f83b 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -560,6 +560,9 @@ extension ProfileViewController { @objc private func followedTagsItemPressed(_ sender: UIBarButtonItem) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + + let followedTagsViewModel = FollowedTagsViewModel(context: context, authContext: viewModel.authContext) + _ = coordinator.present(scene: .followedTags(viewModel: followedTagsViewModel), from: self, transition: .show) } @objc private func refreshControlValueChanged(_ sender: RefreshControl) { diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents index 69ffac191..9f07cca78 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -93,6 +93,7 @@ + @@ -245,11 +246,13 @@ + + \ No newline at end of file diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift index 760985d68..fe668ccb9 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift @@ -77,6 +77,7 @@ final public class MastodonUser: NSManagedObject { @NSManaged public private(set) var votePollOptions: Set @NSManaged public private(set) var votePolls: Set // relationships + @NSManaged public private(set) var followedTags: Set @NSManaged public private(set) var following: Set @NSManaged public private(set) var followingBy: Set @NSManaged public private(set) var followRequested: Set diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift index b5c335db3..51826fe26 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift @@ -24,10 +24,13 @@ public final class Tag: NSManagedObject { @NSManaged public private(set) var name: String // sourcery: autoUpdatableObject, autoGenerateProperty @NSManaged public private(set) var url: String - + // sourcery: autoUpdatableObject, autoGenerateProperty + @NSManaged public private(set) var following: Bool + // one-to-one relationship // many-to-many relationship + @NSManaged public private(set) var followedBy: Set // one-to-many relationship @NSManaged public private(set) var searchHistories: Set @@ -91,12 +94,27 @@ public extension Tag { NSPredicate(format: "%K == %@", #keyPath(Tag.name), name) } + static func predicate(domain: String, following: Bool) -> NSPredicate { + NSPredicate(format: "%K == %@ AND %K == %d", #keyPath(Tag.domain), domain, #keyPath(Tag.following), following) + } + + static func predicate(followedBy user: MastodonUser) -> NSPredicate { + NSPredicate(format: "ANY %K.%K == %@", #keyPath(Tag.followedBy), #keyPath(MastodonUser.id), user.id) + } + static func predicate(domain: String, name: String) -> NSPredicate { NSCompoundPredicate(andPredicateWithSubpredicates: [ predicate(domain: domain), predicate(name: name), ]) } + + static func predicate(domain: String, following: Bool, by user: MastodonUser) -> NSPredicate { + NSCompoundPredicate(andPredicateWithSubpredicates: [ + predicate(domain: domain, following: following), + predicate(followedBy: user) + ]) + } } // MARK: - AutoGenerateProperty @@ -112,6 +130,7 @@ extension Tag: AutoGenerateProperty { public let updatedAt: Date public let name: String public let url: String + public let following: Bool public let histories: [MastodonTagHistory] public init( @@ -121,6 +140,7 @@ extension Tag: AutoGenerateProperty { updatedAt: Date, name: String, url: String, + following: Bool, histories: [MastodonTagHistory] ) { self.identifier = identifier @@ -129,6 +149,7 @@ extension Tag: AutoGenerateProperty { self.updatedAt = updatedAt self.name = name self.url = url + self.following = following self.histories = histories } } @@ -140,12 +161,14 @@ extension Tag: AutoGenerateProperty { self.updatedAt = property.updatedAt self.name = property.name self.url = property.url + self.following = property.following self.histories = property.histories } public func update(property: Property) { update(updatedAt: property.updatedAt) update(url: property.url) + update(following: property.following) update(histories: property.histories) } // sourcery:end @@ -167,12 +190,30 @@ extension Tag: AutoUpdatableObject { self.url = url } } + public func update(following: Bool) { + if self.following != following { + self.following = following + } + } public func update(histories: [MastodonTagHistory]) { if self.histories != histories { self.histories = histories } } // sourcery:end + + public func update(followed: Bool, by mastodonUser: MastodonUser) { + if following { + if !self.followedBy.contains(mastodonUser) { + self.mutableSetValue(forKey: #keyPath(Tag.followedBy)).add(mastodonUser) + } + } else { + if self.followedBy.contains(mastodonUser) { + self.mutableSetValue(forKey: #keyPath(Tag.followedBy)).remove(mastodonUser) + } + } + } + } diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Tag+Property.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Tag+Property.swift index 633f7bddf..7411fd960 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Tag+Property.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Tag+Property.swift @@ -22,6 +22,7 @@ extension Tag.Property { updatedAt: networkDate, name: entity.name, url: entity.url, + following: entity.following ?? false, histories: { guard let histories = entity.history else { return [] } let result: [MastodonTagHistory] = histories.map { history in diff --git a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift new file mode 100644 index 000000000..56c8a043b --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift @@ -0,0 +1,90 @@ +// +// FollowedTagsFetchedResultController.swift +// +// +// Created by Marcus Kida on 23.11.22. +// + +import os.log +import UIKit +import Combine +import CoreData +import CoreDataStack +import MastodonSDK + +public final class FollowedTagsFetchedResultController: NSObject { + + var disposeBag = Set() + + let fetchedResultsController: NSFetchedResultsController + + // input + @Published public var domain: String? = nil + @Published public var user: MastodonUser? = nil + + // output + let _objectIDs = CurrentValueSubject<[NSManagedObjectID], Never>([]) + @Published public private(set) var records: [ManagedObjectRecord] = [] + + public init(managedObjectContext: NSManagedObjectContext, domain: String, user: MastodonUser) { + self.domain = domain + self.fetchedResultsController = { + let fetchRequest = Tag.sortedFetchRequest + fetchRequest.predicate = Tag.predicate(domain: domain, following: true, by: user) + fetchRequest.returnsObjectsAsFaults = false + fetchRequest.fetchBatchSize = 20 + let controller = NSFetchedResultsController( + fetchRequest: fetchRequest, + managedObjectContext: managedObjectContext, + sectionNameKeyPath: nil, + cacheName: nil + ) + + return controller + }() + super.init() + + // debounce output to prevent UI update issues + _objectIDs + .throttle(for: 0.1, scheduler: DispatchQueue.main, latest: true) + .map { objectIDs in objectIDs.map { ManagedObjectRecord(objectID: $0) } } + .assign(to: &$records) + + fetchedResultsController.delegate = self + try? fetchedResultsController.performFetch() + + Publishers.CombineLatest( + self.$domain, + self.$user + ) + .receive(on: DispatchQueue.main) + .sink { [weak self] domain, user in + guard let self = self, let domain = domain, let user = user else { return } + self.fetchedResultsController.fetchRequest.predicate = Tag.predicate(domain: domain, following: true, by: user) + do { + try self.fetchedResultsController.performFetch() + } catch { + assertionFailure(error.localizedDescription) + } + } + .store(in: &disposeBag) + } + +} + +// MARK: - NSFetchedResultsControllerDelegate +extension FollowedTagsFetchedResultController: NSFetchedResultsControllerDelegate { + public func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { + os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + + let objects = fetchedResultsController.fetchedObjects ?? [] + + let items: [NSManagedObjectID] = objects +// .compactMap { object in +// indexes.firstIndex(of: object.id).map { index in (index, object) } +// } +// .sorted { $0.0 < $1.0 } + .map { $0.objectID } + self._objectIDs.value = items + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Tag.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Tag.swift index 5c7130618..3071fed0d 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Tag.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Tag.swift @@ -103,6 +103,9 @@ extension Persistence.Tag { property: property ) update(tag: object, context: context) + if let followingUser = context.me { + object.update(followed: property.following, by: followingUser) + } return object } @@ -116,7 +119,11 @@ extension Persistence.Tag { domain: context.domain, networkDate: context.networkDate ) + tag.update(property: property) + if let followingUser = context.me { + tag.update(followed: property.following, by: followingUser) + } update(tag: tag, context: context) } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift index c27f8cf67..8f89b4b76 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift @@ -163,6 +163,7 @@ extension APIService { } extension APIService { + @discardableResult public func getFollowedTags( domain: String, query: Mastodon.API.Account.FollowedTagsQuery, From ba26dd207625a6a7621a2db5e69dc1ad5567bc74 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 13:43:20 +0100 Subject: [PATCH 257/733] feat: Implement navigating followed tags --- .../FollowedTagsTableViewCell.swift | 4 +++- .../FollowedTagsViewController.swift | 12 ++++++++++++ .../FollowedTags/FollowedTagsViewModel.swift | 18 ++++++++++++++++++ .../FollowedTagsFetchedResultController.swift | 13 ++++--------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift index 47c856313..6adb15a9c 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsTableViewCell.swift @@ -24,9 +24,11 @@ final class FollowedTagsTableViewCell: UITableViewCell { } override func prepareForReuse() { + hashtagView.removeFromSuperview() viewModel = nil - hashtagView = HashtagTimelineHeaderView() + hashtagView = nil super.prepareForReuse() + setup() } } diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift index 0234c638c..6ff3afbcf 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift @@ -61,5 +61,17 @@ extension FollowedTagsViewController { view.addSubview(tableView) tableView.pinToParent() viewModel.setupTableView(tableView) + + viewModel.presentHashtagTimeline + .receive(on: DispatchQueue.main) + .sink { [weak self] hashtagTimelineViewModel in + guard let self = self else { return } + _ = self.coordinator.present( + scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), + from: self, + transition: .show + ) + } + .store(in: &disposeBag) } } diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift index ee3a474b8..e0f1b326a 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift @@ -24,6 +24,9 @@ final class FollowedTagsViewModel: NSObject { let context: AppContext let authContext: AuthContext + // output + let presentHashtagTimeline = PassthroughSubject() + init(context: AppContext, authContext: AuthContext) { self.context = context self.authContext = authContext @@ -115,6 +118,21 @@ extension FollowedTagsViewModel: UITableViewDataSource { extension FollowedTagsViewModel: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(indexPath)") tableView.deselectRow(at: indexPath, animated: true) + + guard + indexPath.section == 0, + let object = fetchedResultsController.records[indexPath.row].object(in: context.managedObjectContext) + else { + return + } + + let hashtagTimelineViewModel = HashtagTimelineViewModel( + context: self.context, + authContext: self.authContext, + hashtag: object.name + ) + presentHashtagTimeline.send(hashtagTimelineViewModel) } } diff --git a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift index 56c8a043b..1398cc7f6 100644 --- a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift +++ b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift @@ -31,6 +31,7 @@ public final class FollowedTagsFetchedResultController: NSObject { self.fetchedResultsController = { let fetchRequest = Tag.sortedFetchRequest fetchRequest.predicate = Tag.predicate(domain: domain, following: true, by: user) + fetchRequest.sortDescriptors = Tag.defaultSortDescriptors fetchRequest.returnsObjectsAsFaults = false fetchRequest.fetchBatchSize = 20 let controller = NSFetchedResultsController( @@ -74,17 +75,11 @@ public final class FollowedTagsFetchedResultController: NSObject { // MARK: - NSFetchedResultsControllerDelegate extension FollowedTagsFetchedResultController: NSFetchedResultsControllerDelegate { - public func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { + public func controllerDidChangeContent(_ controller: NSFetchedResultsController) { os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) let objects = fetchedResultsController.fetchedObjects ?? [] - - let items: [NSManagedObjectID] = objects -// .compactMap { object in -// indexes.firstIndex(of: object.id).map { index in (index, object) } -// } -// .sorted { $0.0 < $1.0 } - .map { $0.objectID } - self._objectIDs.value = items + self._objectIDs.value = objects.map { $0.objectID } + } } From f112e68e7925de614b95b8099549d1f0e9a08db2 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 14:16:58 +0100 Subject: [PATCH 258/733] chore: Add L10n for Followed Tags --- Localization/app.json | 4 ++++ .../Profile/FollowedTags/FollowedTagsViewController.swift | 2 +- Mastodon/Scene/Profile/ProfileViewController.swift | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++++ .../Resources/Base.lproj/Localizable.strings | 3 ++- .../Resources/en.lproj/Localizable.strings | 3 ++- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index ea046bfbc..56d4fa9ed 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -722,6 +722,10 @@ }, "bookmark": { "title": "Bookmarks" + + }, + "followed_tags": { + "title": "Followed Tags" } } } diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift index 6ff3afbcf..9a31fe0c3 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift @@ -42,7 +42,7 @@ extension FollowedTagsViewController { override func viewDidLoad() { super.viewDidLoad() - let _title = "Followed Tags" + let _title = L10n.Scene.FollowedTags.title title = _title titleView.update(title: _title, subtitle: nil) diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 13012f83b..1ee13457b 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -108,7 +108,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi private(set) lazy var followedTagsBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "number"), style: .plain, target: self, action: #selector(ProfileViewController.followedTagsItemPressed(_:))) barButtonItem.tintColor = .white - //barButtonItem.accessibilityLabel = "" TODO: add missing L10n.Common.Controls.Actions.XXXXXX + barButtonItem.accessibilityLabel = L10n.Scene.FollowedTags.title return barButtonItem }() diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 0392d2b05..5b62bf9c1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -633,6 +633,10 @@ public enum L10n { /// Favorited By public static let title = L10n.tr("Localizable", "Scene.FavoritedBy.Title", fallback: "Favorited By") } + public enum FollowedTags { + /// Followed Tags + public static let title = L10n.tr("Localizable", "Scene.FollowedTags.Title", fallback: "Followed Tags") + } public enum Follower { /// Followers from other servers are not displayed. public static let footer = L10n.tr("Localizable", "Scene.Follower.Footer", fallback: "Followers from other servers are not displayed.") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index adeaad07b..c04e6eb83 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -231,6 +231,7 @@ uploaded to Mastodon."; "Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; @@ -461,4 +462,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 2a3f1efbf..71443d816 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -231,6 +231,7 @@ uploaded to Mastodon."; "Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; @@ -461,4 +462,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; From 6a9b29e4a6d04959d40033b7f11c7dcb698ef2e3 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 15:43:02 +0100 Subject: [PATCH 259/733] chore: Add missing L10n --- Localization/app.json | 11 ++++++++++- .../HashtagTimelineHeaderView.swift | 8 ++++---- .../MastodonLocalization/Generated/Strings.swift | 14 ++++++++++++++ .../Resources/Base.lproj/Localizable.strings | 5 +++++ .../Resources/en.lproj/Localizable.strings | 5 +++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 56d4fa9ed..f3225e58c 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -725,7 +725,16 @@ }, "followed_tags": { - "title": "Followed Tags" + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index e8cc48e8f..1b64a1a48 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -105,9 +105,9 @@ private extension HashtagTimelineHeaderView { $0.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) } - postCountDescLabel.text = "posts" - participantsDescLabel.text = "participants" - postsTodayDescLabel.text = "posts today" + postCountDescLabel.text = L10n.Scene.FollowedTags.Header.posts + participantsDescLabel.text = L10n.Scene.FollowedTags.Header.participants + postsTodayDescLabel.text = L10n.Scene.FollowedTags.Header.postsToday followButton.addAction(UIAction(handler: { [weak self] _ in self?.onButtonTapped?() @@ -152,7 +152,7 @@ private extension HashtagTimelineHeaderView { extension HashtagTimelineHeaderView { func update(_ entity: HashtagTimelineHeaderView.Data) { titleLabel.text = "#\(entity.name)" - followButton.setTitle(entity.following == true ? "Unfollow" : "Follow", for: .normal) + followButton.setTitle(entity.following == true ? L10n.Scene.FollowedTags.Actions.unfollow : L10n.Scene.FollowedTags.Actions.follow, for: .normal) followButton.backgroundColor = entity.following == true ? Asset.Colors.Button.tagUnfollow.color : Asset.Colors.Button.tagFollow.color followButton.setTitleColor( diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 5b62bf9c1..34c2b350e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -636,6 +636,20 @@ public enum L10n { public enum FollowedTags { /// Followed Tags public static let title = L10n.tr("Localizable", "Scene.FollowedTags.Title", fallback: "Followed Tags") + public enum Actions { + /// follow + public static let follow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Follow", fallback: "follow") + } + public enum Header { + /// participants + public static let participants = L10n.tr("Localizable", "Scene.FollowedTags.Header.Participants", fallback: "participants") + /// posts + public static let posts = L10n.tr("Localizable", "Scene.FollowedTags.Header.Posts", fallback: "posts") + /// posts today + public static let postsToday = L10n.tr("Localizable", "Scene.FollowedTags.Header.PostsToday", fallback: "posts today") + /// unfollow + public static let unfollow = L10n.tr("Localizable", "Scene.FollowedTags.Header.Unfollow", fallback: "unfollow") + } } public enum Follower { /// Followers from other servers are not displayed. diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index c04e6eb83..6882b0fc5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -232,6 +232,11 @@ uploaded to Mastodon."; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; "Scene.FollowedTags.Title" = "Followed Tags"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Actions.Follow" = "follow"; +"Scene.FollowedTags.Header.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 71443d816..35509900f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -232,6 +232,11 @@ uploaded to Mastodon."; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; "Scene.FollowedTags.Title" = "Followed Tags"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Actions.Follow" = "follow"; +"Scene.FollowedTags.Header.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; From 0c571a2df69eabf2e6165faf3a11089b315c936b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 25 Nov 2022 18:47:49 +0100 Subject: [PATCH 260/733] fix: Localizable string issues --- .../HashtagTimelineHeaderView.swift | 18 ++++++++++++++---- .../Generated/Strings.swift | 4 ++-- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/en.lproj/Localizable.strings | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 1b64a1a48..fac856dc2 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -10,6 +10,7 @@ import CoreDataStack import MastodonSDK import MastodonUI import MastodonAsset +import MastodonLocalization fileprivate extension CGFloat { static let padding: CGFloat = 16 @@ -155,10 +156,19 @@ extension HashtagTimelineHeaderView { followButton.setTitle(entity.following == true ? L10n.Scene.FollowedTags.Actions.unfollow : L10n.Scene.FollowedTags.Actions.follow, for: .normal) followButton.backgroundColor = entity.following == true ? Asset.Colors.Button.tagUnfollow.color : Asset.Colors.Button.tagFollow.color - followButton.setTitleColor( - entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, - for: .normal - ) + + switch traitCollection.userInterfaceStyle { + case .dark: + followButton.setTitleColor( + .lightGray, + for: .normal + ) + default: + followButton.setTitleColor( + entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, + for: .normal + ) + } postCountLabel.text = String(entity.postCount) participantsLabel.text = String(entity.participantsCount) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 34c2b350e..5bed76fce 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -639,6 +639,8 @@ public enum L10n { public enum Actions { /// follow public static let follow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Follow", fallback: "follow") + /// unfollow + public static let unfollow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Unfollow", fallback: "unfollow") } public enum Header { /// participants @@ -647,8 +649,6 @@ public enum L10n { public static let posts = L10n.tr("Localizable", "Scene.FollowedTags.Header.Posts", fallback: "posts") /// posts today public static let postsToday = L10n.tr("Localizable", "Scene.FollowedTags.Header.PostsToday", fallback: "posts today") - /// unfollow - public static let unfollow = L10n.tr("Localizable", "Scene.FollowedTags.Header.Unfollow", fallback: "unfollow") } } public enum Follower { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 6882b0fc5..2fb57c1b3 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -236,7 +236,7 @@ uploaded to Mastodon."; "Scene.FollowedTags.Header.Participants" = "participants"; "Scene.FollowedTags.Header.PostsToday" = "posts today"; "Scene.FollowedTags.Actions.Follow" = "follow"; -"Scene.FollowedTags.Header.Unfollow" = "unfollow"; +"Scene.FollowedTags.Actions.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 35509900f..3d1f4c0a4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -236,7 +236,7 @@ uploaded to Mastodon."; "Scene.FollowedTags.Header.Participants" = "participants"; "Scene.FollowedTags.Header.PostsToday" = "posts today"; "Scene.FollowedTags.Actions.Follow" = "follow"; -"Scene.FollowedTags.Header.Unfollow" = "unfollow"; +"Scene.FollowedTags.Actions.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; From 75dc530dcf5a55b95653e99b2c0f241679fd482e Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 1 Dec 2022 11:39:02 +0100 Subject: [PATCH 261/733] chore: Implement FollowedTagsViewModel+DiffableDataSource --- Mastodon.xcodeproj/project.pbxproj | 4 + ...owedTagsViewModel+DiffableDataSource.swift | 51 ++++++++++++ .../FollowedTags/FollowedTagsViewModel.swift | 79 ++++++------------- .../FollowedTagsFetchedResultController.swift | 16 +--- 4 files changed, 84 insertions(+), 66 deletions(-) create mode 100644 Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel+DiffableDataSource.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index e94871b4d..c5375b7a0 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; }; 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; + 2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */; }; 2A3F6FE3292ECB5E002E6DA7 /* FollowedTagsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */; }; 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; }; 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; @@ -525,6 +526,7 @@ 0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; }; 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; + 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FollowedTagsViewModel+DiffableDataSource.swift"; sourceTree = ""; }; 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewModel.swift; sourceTree = ""; }; 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = ""; }; 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; @@ -1243,6 +1245,7 @@ children = ( 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */, 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */, + 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */, 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */, ); path = FollowedTags; @@ -3398,6 +3401,7 @@ DB938EED2623F79B00E5B6C1 /* ThreadViewModel.swift in Sources */, DB6988DE2848D11C002398EF /* PagerTabStripNavigateable.swift in Sources */, 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */, + 2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */, DB852D1C26FB021500FC9D81 /* RootSplitViewController.swift in Sources */, DB697DD1278F4871004EF2F7 /* AutoGenerateTableViewDelegate.swift in Sources */, DB02CDBF2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift in Sources */, diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel+DiffableDataSource.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel+DiffableDataSource.swift new file mode 100644 index 000000000..91f2cc5e9 --- /dev/null +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel+DiffableDataSource.swift @@ -0,0 +1,51 @@ +// +// FollowedTagsViewModel+DiffableDataSource.swift +// Mastodon +// +// Created by Marcus Kida on 01.12.22. +// + +import UIKit +import Combine +import CoreData +import CoreDataStack +import MastodonSDK +import MastodonCore + +extension FollowedTagsViewModel { + enum Section: Hashable { + case main + } + + enum Item: Hashable { + case hashtag(Tag) + } + + func tableViewDiffableDataSource( + for tableView: UITableView + ) -> UITableViewDiffableDataSource { + UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item in + switch item { + case let .hashtag(tag): + guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: FollowedTagsTableViewCell.self), for: indexPath) as? FollowedTagsTableViewCell else { + assertionFailure() + return UITableViewCell() + } + + cell.setup(self) + cell.populate(with: tag) + return cell + } + } + } + + func setupDiffableDataSource( + tableView: UITableView + ) { + diffableDataSource = tableViewDiffableDataSource(for: tableView) + + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + diffableDataSource?.apply(snapshot) + } +} diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift index e0f1b326a..75464092e 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift @@ -19,7 +19,8 @@ final class FollowedTagsViewModel: NSObject { let fetchedResultsController: FollowedTagsFetchedResultController private weak var tableView: UITableView? - + var diffableDataSource: UITableViewDiffableDataSource? + // input let context: AppContext let authContext: AuthContext @@ -35,12 +36,18 @@ final class FollowedTagsViewModel: NSObject { domain: authContext.mastodonAuthenticationBox.domain, user: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)!.user ) + super.init() + self.fetchedResultsController .$records .receive(on: DispatchQueue.main) - .sink { [weak self] _ in - self?.tableView?.reloadSections(IndexSet(integer: 0), with: .automatic) + .sink { [weak self] records in + guard let self = self else { return } + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + snapshot.appendItems(records.map {.hashtag($0) }) + self.diffableDataSource?.applySnapshot(snapshot, animated: true) } .store(in: &disposeBag) } @@ -49,29 +56,22 @@ final class FollowedTagsViewModel: NSObject { extension FollowedTagsViewModel { func setupTableView(_ tableView: UITableView) { self.tableView = tableView - tableView.dataSource = self + setupDiffableDataSource(tableView: tableView) tableView.delegate = self - fetchFollowedTags { - tableView.reloadData() + fetchFollowedTags() + } + + func fetchFollowedTags() { + Task { @MainActor in + try await context.apiService.getFollowedTags( + domain: authContext.mastodonAuthenticationBox.domain, + query: Mastodon.API.Account.FollowedTagsQuery(limit: nil), + authenticationBox: authContext.mastodonAuthenticationBox + ) } } - - func fetchFollowedTags(_ done: @escaping () -> Void) { - Task { @MainActor [weak self] in - try? await self?._fetchFollowedTags() - done() - } - } - - private func _fetchFollowedTags() async throws { - try await context.apiService.getFollowedTags( - domain: authContext.mastodonAuthenticationBox.domain, - query: Mastodon.API.Account.FollowedTagsQuery(limit: nil), - authenticationBox: authContext.mastodonAuthenticationBox - ) - } - + func followOrUnfollow(_ tag: Tag) { Task { @MainActor in switch tag.following { @@ -86,53 +86,24 @@ extension FollowedTagsViewModel { authenticationBox: authContext.mastodonAuthenticationBox ) } - try? await _fetchFollowedTags() + fetchFollowedTags() } } } -extension FollowedTagsViewModel: UITableViewDataSource { - func numberOfSections(in tableView: UITableView) -> Int { - 1 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - fetchedResultsController.records.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard - indexPath.section == 0, - let object = fetchedResultsController.records[indexPath.row].object(in: context.managedObjectContext) - else { - return UITableViewCell() - } - - let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: FollowedTagsTableViewCell.self), for: indexPath) as! FollowedTagsTableViewCell - - cell.setup(self) - cell.populate(with: object) - return cell - } -} - extension FollowedTagsViewModel: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(indexPath)") tableView.deselectRow(at: indexPath, animated: true) - guard - indexPath.section == 0, - let object = fetchedResultsController.records[indexPath.row].object(in: context.managedObjectContext) - else { - return - } + let object = fetchedResultsController.records[indexPath.row] let hashtagTimelineViewModel = HashtagTimelineViewModel( context: self.context, authContext: self.authContext, hashtag: object.name ) + presentHashtagTimeline.send(hashtagTimelineViewModel) } } diff --git a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift index 1398cc7f6..8c5c64b58 100644 --- a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift +++ b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/FollowedTagsFetchedResultController.swift @@ -23,8 +23,7 @@ public final class FollowedTagsFetchedResultController: NSObject { @Published public var user: MastodonUser? = nil // output - let _objectIDs = CurrentValueSubject<[NSManagedObjectID], Never>([]) - @Published public private(set) var records: [ManagedObjectRecord] = [] + @Published public private(set) var records: [Tag] = [] public init(managedObjectContext: NSManagedObjectContext, domain: String, user: MastodonUser) { self.domain = domain @@ -44,13 +43,7 @@ public final class FollowedTagsFetchedResultController: NSObject { return controller }() super.init() - - // debounce output to prevent UI update issues - _objectIDs - .throttle(for: 0.1, scheduler: DispatchQueue.main, latest: true) - .map { objectIDs in objectIDs.map { ManagedObjectRecord(objectID: $0) } } - .assign(to: &$records) - + fetchedResultsController.delegate = self try? fetchedResultsController.performFetch() @@ -75,11 +68,10 @@ public final class FollowedTagsFetchedResultController: NSObject { // MARK: - NSFetchedResultsControllerDelegate extension FollowedTagsFetchedResultController: NSFetchedResultsControllerDelegate { - public func controllerDidChangeContent(_ controller: NSFetchedResultsController) { + public func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) let objects = fetchedResultsController.fetchedObjects ?? [] - self._objectIDs.value = objects.map { $0.objectID } - + self.records = objects } } From 270bb6a1ed32d845447a88d3ad8124014622b560 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 1 Dec 2022 12:38:23 +0100 Subject: [PATCH 262/733] fix: Update HashtagTimelineHeaderView if follow state changes --- Mastodon.xcodeproj/project.pbxproj | 4 ++++ Mastodon/Extension/Collection+IsNotEmpty.swift | 14 ++++++++++++++ .../HashtagTimelineViewController.swift | 1 + .../HashtagTimeline/HashtagTimelineViewModel.swift | 14 ++++++++++++++ .../CoreDataStack/Entity/Mastodon/Tag.swift | 3 ++- 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Mastodon/Extension/Collection+IsNotEmpty.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index c5375b7a0..96404cebb 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; }; 18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; }; 2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */; }; + 2A1FE47E2938C11200784BF1 /* Collection+IsNotEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */; }; 2A3F6FE3292ECB5E002E6DA7 /* FollowedTagsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */; }; 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; }; 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; @@ -527,6 +528,7 @@ 164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; }; 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; }; 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FollowedTagsViewModel+DiffableDataSource.swift"; sourceTree = ""; }; + 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+IsNotEmpty.swift"; sourceTree = ""; }; 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewModel.swift; sourceTree = ""; }; 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = ""; }; 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; @@ -2275,6 +2277,7 @@ DBCC3B2F261440A50045B23D /* UITabBarController.swift */, DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */, DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */, + 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */, ); path = Extension; sourceTree = ""; @@ -3322,6 +3325,7 @@ 2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */, DB0FCB842796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift in Sources */, DB0FCB68279507EF006C02E2 /* DataSourceFacade+Meta.swift in Sources */, + 2A1FE47E2938C11200784BF1 /* Collection+IsNotEmpty.swift in Sources */, 2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */, 6213AF5A28939C8400BCADB6 /* BookmarkViewModel.swift in Sources */, 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */, diff --git a/Mastodon/Extension/Collection+IsNotEmpty.swift b/Mastodon/Extension/Collection+IsNotEmpty.swift new file mode 100644 index 000000000..d59b8e2fe --- /dev/null +++ b/Mastodon/Extension/Collection+IsNotEmpty.swift @@ -0,0 +1,14 @@ +// +// Array+IsNotEmpty.swift +// Mastodon +// +// Created by Marcus Kida on 01.12.22. +// + +import Foundation + +extension Collection { + var isNotEmpty: Bool { + !isEmpty + } +} diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 380098559..b1e4ad40a 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -139,6 +139,7 @@ extension HashtagTimelineViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + viewModel.viewWillAppear() tableView.deselectRow(with: transitionCoordinator, animated: animated) } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift index f4e7ef428..888bc720c 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift @@ -70,6 +70,20 @@ final class HashtagTimelineViewModel { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s:", ((#file as NSString).lastPathComponent), #line, #function) } + func viewWillAppear() { + let predicate = Tag.predicate( + domain: authContext.mastodonAuthenticationBox.domain, + name: hashtag + ) + + guard + let object = Tag.findOrFetch(in: context.managedObjectContext, matching: predicate) + else { + return hashtagDetails.send(hashtagDetails.value?.copy(following: false)) + } + + hashtagDetails.send(hashtagDetails.value?.copy(following: object.following)) + } } extension HashtagTimelineViewModel { diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift index 51826fe26..cd9799034 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift @@ -91,7 +91,8 @@ public extension Tag { } static func predicate(name: String) -> NSPredicate { - NSPredicate(format: "%K == %@", #keyPath(Tag.name), name) + // use case-insensitive query as tags #CaN #BE #speLLed #USiNG #arbITRARy #cASe + NSPredicate(format: "%K contains[c] %@", #keyPath(Tag.name), name) } static func predicate(domain: String, following: Bool) -> NSPredicate { From bf5a0917988620956aa69eed60de502b3a95013b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 1 Dec 2022 14:24:54 +0100 Subject: [PATCH 263/733] chore: Improve Tag.predicate(name:) case-insensitivity --- MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift index cd9799034..8332f3d4c 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Tag.swift @@ -92,7 +92,7 @@ public extension Tag { static func predicate(name: String) -> NSPredicate { // use case-insensitive query as tags #CaN #BE #speLLed #USiNG #arbITRARy #cASe - NSPredicate(format: "%K contains[c] %@", #keyPath(Tag.name), name) + NSPredicate(format: "%K MATCHES[c] %@", #keyPath(Tag.name), name) } static func predicate(domain: String, following: Bool) -> NSPredicate { From 324e782fd5e04434e22b4a9a52a08bd3d33e4241 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 1 Dec 2022 14:31:56 +0100 Subject: [PATCH 264/733] chore: Improve Hashtag Header Post Count label alignment --- .../Scene/HashtagTimeline/HashtagTimelineHeaderView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index fac856dc2..998b774b6 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -124,8 +124,8 @@ private extension HashtagTimelineHeaderView { titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -CGFloat.padding), postCountLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: .padding), - postCountLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), - postCountDescLabel.leadingAnchor.constraint(equalTo: postCountLabel.leadingAnchor), + postCountLabel.centerXAnchor.constraint(equalTo: postCountDescLabel.centerXAnchor), + postCountDescLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), participantsDescLabel.leadingAnchor.constraint(equalTo: postCountDescLabel.trailingAnchor, constant: .descriptionLabelSpacing), participantsLabel.centerXAnchor.constraint(equalTo: participantsDescLabel.centerXAnchor), From 6c2fabaa039676821c33c62f1a7d5a8fbddb6195 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 1 Dec 2022 14:52:55 +0100 Subject: [PATCH 265/733] chore: Fix hashtag follow button style --- .../HashtagTimelineHeaderView.swift | 16 ++++------------ .../HashtagTimelineHeaderViewActionButton.swift | 11 ++++++++++- .../Button/tagFollow.colorset/Contents.json | 8 ++++---- .../Button/tagUnfollow.colorset/Contents.json | 2 +- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 998b774b6..3af2cf07b 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -157,18 +157,10 @@ extension HashtagTimelineHeaderView { followButton.backgroundColor = entity.following == true ? Asset.Colors.Button.tagUnfollow.color : Asset.Colors.Button.tagFollow.color - switch traitCollection.userInterfaceStyle { - case .dark: - followButton.setTitleColor( - .lightGray, - for: .normal - ) - default: - followButton.setTitleColor( - entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, - for: .normal - ) - } + followButton.setTitleColor( + entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, + for: .normal + ) postCountLabel.text = String(entity.postCount) participantsLabel.text = String(entity.participantsCount) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift index aff97b21c..7efeb15d0 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift @@ -22,8 +22,17 @@ class HashtagTimelineHeaderViewActionButton: RoundedEdgesButton { public override func layoutSubviews() { super.layoutSubviews() + let shadowColor: UIColor = { + switch traitCollection.userInterfaceStyle { + case .dark: + return .darkGray + default: + return .lightGray + } + }() + layer.setupShadow( - color: .lightGray, + color: shadowColor, alpha: 1, x: 0, y: 1, diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json index 9bc42278d..e7e41c6ff 100644 --- a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagFollow.colorset/Contents.json @@ -22,10 +22,10 @@ "color" : { "color-space" : "srgb", "components" : { - "alpha" : "0.700", - "blue" : "0x38", - "green" : "0x29", - "red" : "0x2B" + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" } }, "idiom" : "universal" diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json index 2790f171d..e7fbb60a6 100644 --- a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Colors/Button/tagUnfollow.colorset/Contents.json @@ -22,7 +22,7 @@ "color" : { "color-space" : "srgb", "components" : { - "alpha" : "0.250", + "alpha" : "1.000", "blue" : "0x38", "green" : "0x29", "red" : "0x2B" From d082ffbfa03c38cbc91dba27c451c988c34ff20b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:14 +0100 Subject: [PATCH 266/733] New translations app.json (Slovenian) --- .../StringsConvertor/input/sl.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index f37d088a7..892d12efe 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Zaznamki" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From a55d977b1bd39989c0808f23004edd9dc8b1b05e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:16 +0100 Subject: [PATCH 267/733] New translations app.json (Latvian) --- .../StringsConvertor/input/lv.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index c978536c7..cc0f99402 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 579f475f60afed60971f3b76eb3a94eb95fc9ac3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:17 +0100 Subject: [PATCH 268/733] New translations app.json (Chinese Simplified) --- .../StringsConvertor/input/zh-Hans.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 1ba63107c..1483b546e 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "书签" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From d8261d1d730e51a720a7e0cebe945f69298846a1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:18 +0100 Subject: [PATCH 269/733] New translations app.json (English) --- .../StringsConvertor/input/en.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index c757b4979..e13aac13c 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 0243097c957f2a02930859594f492894795f1e52 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:19 +0100 Subject: [PATCH 270/733] New translations app.json (Galician) --- .../StringsConvertor/input/gl.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 3d3f74971..68bd472f4 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Marcadores" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From f79a4147e0653b39d70e8c2892f626c9197ffd8a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:20 +0100 Subject: [PATCH 271/733] New translations app.json (Portuguese, Brazilian) --- .../StringsConvertor/input/pt-BR.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 770b42167..c10341baf 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Marcados" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 3f940d4e3ab1af33c6c3f1289fc7cbd0242c12d6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:21 +0100 Subject: [PATCH 272/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index c2dd3c215..b043bfea3 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Tandai" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 7b463cf935032ce27e72d9499c55b4e69e8efe1d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:22 +0100 Subject: [PATCH 273/733] New translations app.json (Spanish, Argentina) --- .../StringsConvertor/input/es-AR.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index cf2b521c2..396d23e4b 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Marcadores" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From bf3a85c48cc2fee992669c4b744f4641cb72acfe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:23 +0100 Subject: [PATCH 274/733] New translations app.json (Thai) --- .../StringsConvertor/input/th.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 7bcf5da60..1987f015a 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "ที่คั่นหน้า" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From f855977d86797430ca21c337274000be43728ff6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:24 +0100 Subject: [PATCH 275/733] New translations app.json (Hindi) --- .../StringsConvertor/input/hi.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 8a90d73af..9d044bf88 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From dde7f7d04218ae1ee614e1ca6dbcaf83f7514761 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:25 +0100 Subject: [PATCH 276/733] New translations app.json (Portuguese) --- .../StringsConvertor/input/pt.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index c757b4979..e13aac13c 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 6f3f79ff208740aff3934efc8848fcaa6b6dd4c5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:26 +0100 Subject: [PATCH 277/733] New translations app.json (English, United States) --- .../StringsConvertor/input/en-US.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index c757b4979..e13aac13c 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From ac1da7d99aaff9fd361e34f71c51bdf2fbe1a36f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:27 +0100 Subject: [PATCH 278/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 4087a963e..d83ac8b5a 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Tudalnodau" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From d8a906b92521551ef3d1fc5e3333e8ecf5854a49 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:28 +0100 Subject: [PATCH 279/733] New translations app.json (Sinhala) --- .../StringsConvertor/input/si.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 6f48afe07..49f52a300 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From db70df51fe6713dae36855d44d38a4396822dec5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:29 +0100 Subject: [PATCH 280/733] New translations app.json (Kurmanji (Kurdish)) --- .../StringsConvertor/input/kmr.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 8f83803b3..82f188f88 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Şûnpel" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From ad8c48e05e5109bd5486d27b414a010bd308bfc3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:30 +0100 Subject: [PATCH 281/733] New translations app.json (Sorani (Kurdish)) --- .../StringsConvertor/input/ckb.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index ff5a38e35..7a21fe254 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 8c65848a861c41a851d6518aeac70fd0f161da5f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:31 +0100 Subject: [PATCH 282/733] New translations app.json (Icelandic) --- .../StringsConvertor/input/is.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index b3ce68632..fe8289403 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bókamerki" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 7c871576ec69b4fec90ccad43d5159fa1e530e10 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:33 +0100 Subject: [PATCH 283/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 5877396f2..8a6dacd5c 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 8db77f481da2e560d7900d3bb83b063c74147cd3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:34 +0100 Subject: [PATCH 284/733] New translations app.json (Aragonese) --- .../StringsConvertor/input/an.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 4a9c690f0..c4cf36e7e 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Marcapachinas" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From a0a3e5bf72cfd3689e21f4f2ecb14962ab431197 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:35 +0100 Subject: [PATCH 285/733] New translations app.json (Russian) --- .../StringsConvertor/input/ru.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index e71c41049..192e77d0a 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 02aa10d2457ab9d18382f126dddcd244a55491d8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:36 +0100 Subject: [PATCH 286/733] New translations app.json (Dutch) --- .../StringsConvertor/input/nl.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 404034edc..4f36a58fd 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 41279b6f111bb1a6134b96e1d58e6be9587cee57 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:37 +0100 Subject: [PATCH 287/733] New translations app.json (Chinese Traditional) --- .../StringsConvertor/input/zh-Hant.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 209beb2d8..e6b1bfe5f 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "書籤" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 7e134ac29f0ede6c7bf003d191cafa6bc2aed76e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:38 +0100 Subject: [PATCH 288/733] New translations app.json (Scottish Gaelic) --- .../StringsConvertor/input/gd.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 25de9c917..e7e0be2cf 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Comharran-lìn" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From c7917a42f255a2a42bd4d405fa076fa688c4a5b9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:39 +0100 Subject: [PATCH 289/733] New translations app.json (Vietnamese) --- .../StringsConvertor/input/vi.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index c688673e0..9a864e13b 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Tút đã lưu" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 3227f257620ffb8bc96602a7b5cee3fd7e7636fd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:40 +0100 Subject: [PATCH 290/733] New translations app.json (Kabyle) --- .../StringsConvertor/input/kab.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 2687e1dfd..1965b3243 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From ae67b667edc93a8db4ca728de56b0afc0d62a1ba Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:41 +0100 Subject: [PATCH 291/733] New translations app.json (Korean) --- .../StringsConvertor/input/ko.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 4cf5c3de5..d5ff14190 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From fd31e6ec3aff2a03932d66d16214c9c461b8d1a5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:42 +0100 Subject: [PATCH 292/733] New translations app.json (Swedish) --- .../StringsConvertor/input/sv.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index c19d4c628..8535dcd40 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bokmärken" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 976f866d3ecbc995580c10a22790d00eba1d476f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:43 +0100 Subject: [PATCH 293/733] New translations app.json (French) --- .../StringsConvertor/input/fr.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index b061fee34..a6bf264a5 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Favoris" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 7334bb7497386cd4495020801a25936b97517d03 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:45 +0100 Subject: [PATCH 294/733] New translations app.json (Turkish) --- .../StringsConvertor/input/tr.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index dc3aadb9c..2b3150750 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Yer İmleri" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 012f71fdd73d56bdb247bf5233a196755cd87653 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:46 +0100 Subject: [PATCH 295/733] New translations app.json (Czech) --- .../StringsConvertor/input/cs.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 318b404cf..a69d83041 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Záložky" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From e3f385079f1f11ca5215d4332a8d208207a255c2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:47 +0100 Subject: [PATCH 296/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 513137936..b94eb5f2d 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Закладки" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 9988020b849d1e3dcbcecf12bc47a2075e067f34 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:48 +0100 Subject: [PATCH 297/733] New translations app.json (Romanian) --- .../StringsConvertor/input/ro.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index f65c3b1be..ed3882abc 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From b50588317396d27efb5cd1ffb35afb4d5c4bac60 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:49 +0100 Subject: [PATCH 298/733] New translations app.json (Japanese) --- .../StringsConvertor/input/ja.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 3d3bd173c..225d7458b 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "ブックマーク" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 4d6da6859dab399d2d1d4bbf73e4b035016c3051 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:50 +0100 Subject: [PATCH 299/733] New translations app.json (Spanish) --- .../StringsConvertor/input/es.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index cab7e70fb..82378bb8e 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 6494abccb929f97ce17feeb2c4ef8112013f53d2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:51 +0100 Subject: [PATCH 300/733] New translations app.json (Arabic) --- .../StringsConvertor/input/ar.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 8e09a81cb..c995e4c87 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "العَلاماتُ المَرجعيَّة" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From ba23269533da8817fae484f01c5d92490fa9cca0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:52 +0100 Subject: [PATCH 301/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 42c11c9b5..4e68315b8 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Marcadors" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 7462b4a91afe730d5efbc8f57dabe37f8735de69 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:53 +0100 Subject: [PATCH 302/733] New translations app.json (Danish) --- .../StringsConvertor/input/da.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index c757b4979..e13aac13c 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 4e361adc9345925df5bb3e6a4e426a381f78319a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:54 +0100 Subject: [PATCH 303/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 00c5b735f..e28f3338c 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -66,7 +66,7 @@ "ok": "OK", "done": "Fertig", "confirm": "Bestätigen", - "continue": "Fortfahren", + "continue": "Weiter", "compose": "Neue Nachricht", "cancel": "Abbrechen", "discard": "Verwerfen", @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Lesezeichen" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 96d7fa9282e0c9dbc1ec6a04970c7fee8a0177be Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:55 +0100 Subject: [PATCH 304/733] New translations app.json (Basque) --- .../StringsConvertor/input/eu.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 4a50606a9..ad785bec4 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Laster-markak" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From f5b9bfe829176ad8d6cc0ee39499cd6b235350b8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:56 +0100 Subject: [PATCH 305/733] New translations app.json (Finnish) --- .../StringsConvertor/input/fi.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index c575a9144..14682e8e8 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From e567ade3e6a9ee5f96cbcf70b5e0c538620aad72 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:57 +0100 Subject: [PATCH 306/733] New translations app.json (Italian) --- .../StringsConvertor/input/it.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 2cd40458e..20a1cbf47 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Segnalibri" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From ac68c6c7fc0330299f70cd636ec165cbdf8db6ea Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 20:49:59 +0100 Subject: [PATCH 307/733] New translations app.json (Hebrew) --- .../StringsConvertor/input/he.lproj/app.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 32bd75cdf..9517a2540 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -722,6 +722,18 @@ }, "bookmark": { "title": "Bookmarks" + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } From 39412a992afb8de677c0226e9ef217100513bb94 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:19 +0100 Subject: [PATCH 308/733] New translations app.json (Slovenian) --- .../StringsConvertor/input/sl.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 892d12efe..9453cb422 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Domov", - "search": "Iskanje", + "search_and_explore": "Search and Explore", "notifications": "Obvestila", "profile": "Profil" }, @@ -724,15 +724,15 @@ "title": "Zaznamki" }, "followed_tags": { - "title": "Followed Tags", + "title": "Sledene značke", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "objav", + "participants": "udeležencev", + "posts_today": "objav danes" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Sledi", + "unfollow": "Prenehaj slediti" } } } From da730b14044bfe13a3c9e5bf97428d8bcdfc1c97 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:20 +0100 Subject: [PATCH 309/733] New translations app.json (Latvian) --- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index cc0f99402..e65535159 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Sākums", - "search": "Meklēšana", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profils" }, From b54a565a866a964a0b9c81bf196658ae1da55b49 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:21 +0100 Subject: [PATCH 310/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 1483b546e..6bf633d09 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "主页", - "search": "搜索", + "search_and_explore": "Search and Explore", "notifications": "通知", "profile": "个人资料" }, From a71a4117ddf5ac137b69b260ef65ecbe4468cd9b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:22 +0100 Subject: [PATCH 311/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index e13aac13c..85940744c 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 2c38e4d7c9df14354ddd5e73d196521df116bdb6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:23 +0100 Subject: [PATCH 312/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 68bd472f4..a2af2e2b2 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inicio", - "search": "Busca", + "search_and_explore": "Search and Explore", "notifications": "Notificacións", "profile": "Perfil" }, From f1b266773e4fa6f0e80ba28ace9849c4600615c7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:24 +0100 Subject: [PATCH 313/733] New translations app.json (Portuguese, Brazilian) --- Localization/StringsConvertor/input/pt-BR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index c10341baf..2f460619f 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Início", - "search": "Buscar", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Perfil" }, From fc0547fdb915f1149efadb15426a53882275b3b8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:25 +0100 Subject: [PATCH 314/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index b043bfea3..1ba4ea601 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Beranda", - "search": "Cari", + "search_and_explore": "Search and Explore", "notifications": "Notifikasi", "profile": "Profil" }, From 705625cdf090d6aeec19cf570357c56981ffb4d2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:26 +0100 Subject: [PATCH 315/733] New translations app.json (Spanish, Argentina) --- .../StringsConvertor/input/es-AR.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 396d23e4b..722ac04e6 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Principal", - "search": "Buscar", + "search_and_explore": "Search and Explore", "notifications": "Notificaciones", "profile": "Perfil" }, @@ -724,15 +724,15 @@ "title": "Marcadores" }, "followed_tags": { - "title": "Followed Tags", + "title": "Etiquetas seguidas", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "mensajes", + "participants": "participantes", + "posts_today": "mensajes hoy" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Seguir", + "unfollow": "Dejar de seguir" } } } From 8393c3b134a189f96365d19791ed3e8e1582bebb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:28 +0100 Subject: [PATCH 316/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 1987f015a..7fdd0e66c 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "หน้าแรก", - "search": "ค้นหา", + "search_and_explore": "Search and Explore", "notifications": "การแจ้งเตือน", "profile": "โปรไฟล์" }, From c617d7c43d389fcddf03a0ace85b672cd2372063 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:29 +0100 Subject: [PATCH 317/733] New translations app.json (Hindi) --- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 9d044bf88..471c7b036 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 51c276643427f05511620563f0b14771f965fb24 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:30 +0100 Subject: [PATCH 318/733] New translations app.json (Portuguese) --- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index e13aac13c..85940744c 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 64000486e68283a3711d7aa54fe6ff0746f7bdb8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:31 +0100 Subject: [PATCH 319/733] New translations app.json (English, United States) --- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index e13aac13c..85940744c 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 9bed81038d635068aeea6a86db4025c862e01e58 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:32 +0100 Subject: [PATCH 320/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index d83ac8b5a..680ba2ac1 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Hafan", - "search": "Chwilio", + "search_and_explore": "Search and Explore", "notifications": "Hysbysiadau", "profile": "Proffil" }, From 1391a58ba43304419ef105f8a557d9706e7b7fce Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:34 +0100 Subject: [PATCH 321/733] New translations app.json (Sinhala) --- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 49f52a300..7440c5e31 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 7754b0d04148cddf8d9f140eb72606c9d1b86071 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:35 +0100 Subject: [PATCH 322/733] New translations app.json (Kurmanji (Kurdish)) --- .../StringsConvertor/input/kmr.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 82f188f88..768e9c167 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Serrûpel", - "search": "Bigere", + "search_and_explore": "Search and Explore", "notifications": "Agahdarî", "profile": "Profîl" }, @@ -724,15 +724,15 @@ "title": "Şûnpel" }, "followed_tags": { - "title": "Followed Tags", + "title": "Hashtagên şopandî", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "şandî", + "participants": "beşdar", + "posts_today": "şandiyên îro" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Bişopîne", + "unfollow": "Neşopîne" } } } From 349db4b541f81001018d13ba351d6983701a2d48 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:37 +0100 Subject: [PATCH 323/733] New translations app.json (Sorani (Kurdish)) --- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 7a21fe254..73258f53f 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "ماڵەوە", - "search": "بگەڕێ", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "پرۆفایل" }, From 5ad524c3a14d6d6648a68168072f62263647bdd2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:38 +0100 Subject: [PATCH 324/733] New translations app.json (Icelandic) --- .../StringsConvertor/input/is.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index fe8289403..bf9439aa9 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Heim", - "search": "Leita", + "search_and_explore": "Search and Explore", "notifications": "Tilkynningar", "profile": "Notandasnið" }, @@ -724,15 +724,15 @@ "title": "Bókamerki" }, "followed_tags": { - "title": "Followed Tags", + "title": "Myllumerki sem fylgst er með", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "færslur", + "participants": "þátttakendur", + "posts_today": "færslur í dag" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Fylgjast með", + "unfollow": "Hætta að fylgjast með" } } } From ffb596e605c2e4112d323aa0ae179529ef8fc25c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:39 +0100 Subject: [PATCH 325/733] New translations app.json (Burmese) --- Localization/StringsConvertor/input/my.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 8a6dacd5c..8adf8459a 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "အိမ်", - "search": "ရှာဖွေရန်", + "search_and_explore": "Search and Explore", "notifications": "အသိပေးချက်များ", "profile": "ကိုယ်ရေးမှတ်တမ်း" }, From 1ca908b3bfbbef9f5d8ec36e02f33e58075c904a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:40 +0100 Subject: [PATCH 326/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index c4cf36e7e..c81bb7e1c 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inicio", - "search": "Buscar", + "search_and_explore": "Search and Explore", "notifications": "Notificacions", "profile": "Perfil" }, From b656357075e3a0117fc79aa9823140221d3762e5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:41 +0100 Subject: [PATCH 327/733] New translations app.json (Russian) --- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 192e77d0a..0c906b579 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Главная", - "search": "Поиск", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Профиль" }, From 050caf9768e761c1874d0eb0001947dddd152670 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:42 +0100 Subject: [PATCH 328/733] New translations app.json (Dutch) --- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 4f36a58fd..d38fff6c1 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Start", - "search": "Zoek", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profiel" }, From a5569fd762c42636d681acb36f14121e966d3c5a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:43 +0100 Subject: [PATCH 329/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index e6b1bfe5f..41840f45d 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "首頁", - "search": "搜尋", + "search_and_explore": "Search and Explore", "notifications": "通知", "profile": "個人檔案" }, From 0816b936293e0dbcea480f24f3eb1acfee8394c8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:45 +0100 Subject: [PATCH 330/733] New translations app.json (Scottish Gaelic) --- Localization/StringsConvertor/input/gd.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index e7e0be2cf..57f5c2c14 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Dachaigh", - "search": "Lorg", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Pròifil" }, From 3cf83b5411f86217212cfd2085acaba94f2afad2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:46 +0100 Subject: [PATCH 331/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 9a864e13b..5cc1d3018 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Bảng tin", - "search": "Tìm kiếm", + "search_and_explore": "Search and Explore", "notifications": "Thông báo", "profile": "Trang hồ sơ" }, From ef90f55be383d182133543e6de5a5eecc5b31b42 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:47 +0100 Subject: [PATCH 332/733] New translations app.json (Kabyle) --- Localization/StringsConvertor/input/kab.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 1965b3243..709a52d0f 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Agejdan", - "search": "Nadi", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Amaɣnu" }, From 520c4e09f22b58be2c7a3bbf62eb9b78638e146c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:48 +0100 Subject: [PATCH 333/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index d5ff14190..d964670a9 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "홈", - "search": "검색", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "프로필" }, From b394d7ec1aa452c04b68ce96ac47611bb716137b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:49 +0100 Subject: [PATCH 334/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 8535dcd40..a5393aa4b 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Hem", - "search": "Sök", + "search_and_explore": "Search and Explore", "notifications": "Notiser", "profile": "Profil" }, From c5674af4250bfafbe6098191ac035fc3f64deae7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:50 +0100 Subject: [PATCH 335/733] New translations app.json (French) --- Localization/StringsConvertor/input/fr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index a6bf264a5..7c77c0967 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Accueil", - "search": "Rechercher", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profil" }, From 45373381336d953b8422e82b82044b09ffe87fbf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:51 +0100 Subject: [PATCH 336/733] New translations app.json (Turkish) --- Localization/StringsConvertor/input/tr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 2b3150750..9be7bbfe5 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Ana Sayfa", - "search": "Arama", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profil" }, From 3b58dd50e829dae867f857cd4df66927f3c6d75b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:52 +0100 Subject: [PATCH 337/733] New translations app.json (Czech) --- .../StringsConvertor/input/cs.lproj/app.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index a69d83041..cfa49cd7c 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -95,8 +95,8 @@ }, "tabs": { "home": "Domů", - "search": "Hledat", - "notifications": "Notifications", + "search_and_explore": "Search and Explore", + "notifications": "Oznámení", "profile": "Profil" }, "keyboard": { @@ -113,7 +113,7 @@ "open_author_profile": "Otevřít profil autora", "open_reblogger_profile": "Otevřít rebloggerův profil", "reply_status": "Odpovědět na příspěvek", - "toggle_reblog": "Toggle Reblog on Post", + "toggle_reblog": "Přepnout Reblog na příspěvku", "toggle_favorite": "Toggle Favorite on Post", "toggle_content_warning": "Přepnout varování obsahu", "preview_image": "Náhled obrázku" @@ -724,15 +724,15 @@ "title": "Záložky" }, "followed_tags": { - "title": "Followed Tags", + "title": "Sledované štítky", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "příspěvky", + "participants": "účastníci", + "posts_today": "příspěvky dnes" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Sledovat", + "unfollow": "Přestat sledovat" } } } From 3334da6caa46486f122b17897aa11fa16c31ec6f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:54 +0100 Subject: [PATCH 338/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index b94eb5f2d..62be7ac9d 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Головна", - "search": "Пошук", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Профіль" }, From d55d297d7843c8f0608b7a1172553553a929eccb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:55 +0100 Subject: [PATCH 339/733] New translations app.json (Romanian) --- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index ed3882abc..2ce7d060f 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Acasă", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From baf7d553cc2a83da38c1b536fa1a30c0ddc5d607 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:56 +0100 Subject: [PATCH 340/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 225d7458b..2642bdf71 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "ホーム", - "search": "検索", + "search_and_explore": "Search and Explore", "notifications": "通知", "profile": "プロフィール" }, From 5aa80897a0870893d25e2f2da6f536f107d84cf8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:57 +0100 Subject: [PATCH 341/733] New translations app.json (Spanish) --- Localization/StringsConvertor/input/es.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 82378bb8e..a2709f3ff 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inicio", - "search": "Buscar", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Perfil" }, From c19a0fe3a3054a74951c54a9988c4acab61a70d4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:58 +0100 Subject: [PATCH 342/733] New translations app.json (Arabic) --- .../StringsConvertor/input/ar.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index c995e4c87..8d2643a3f 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "الرَّئِيسَة", - "search": "البَحث", + "search_and_explore": "Search and Explore", "notifications": "الإشعارات", "profile": "المِلَفُّ التَّعريفِيّ" }, @@ -724,15 +724,15 @@ "title": "العَلاماتُ المَرجعيَّة" }, "followed_tags": { - "title": "Followed Tags", + "title": "وُسُومُ المُتابَع", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "مَنشورات", + "participants": "المُشارِكُون", + "posts_today": "مَنشوراتُ اليَوم" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "مُتابَعَة", + "unfollow": "إلغاءُ المُتابَعَة" } } } From 3fa26b26374c778da0d284482804864b98f56ce8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:52:59 +0100 Subject: [PATCH 343/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 4e68315b8..900feaa3e 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inici", - "search": "Cerca", + "search_and_explore": "Search and Explore", "notifications": "Notificacions", "profile": "Perfil" }, @@ -724,15 +724,15 @@ "title": "Marcadors" }, "followed_tags": { - "title": "Followed Tags", + "title": "Etiquetes seguides", "header": { - "posts": "posts", + "posts": "tuts", "participants": "participants", - "posts_today": "posts today" + "posts_today": "tuts d'avui" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Segueix", + "unfollow": "Deixa de seguir" } } } From c6392986bc3dbd92b3a50233dd1d3e82e864cf0d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:00 +0100 Subject: [PATCH 344/733] New translations app.json (Danish) --- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index e13aac13c..85940744c 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profile" }, From 3518e82b7373bdb2354ec237635805543e45bd04 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:01 +0100 Subject: [PATCH 345/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index e28f3338c..31ecc8a9a 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Startseite", - "search": "Suche", + "search_and_explore": "Search and Explore", "notifications": "Mitteilungen", "profile": "Profil" }, From 468abd28adb09f7244c00672b073df81cff06c34 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:02 +0100 Subject: [PATCH 346/733] New translations app.json (Basque) --- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index ad785bec4..6a6c5a5c2 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Hasiera", - "search": "Bilatu", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profila" }, From e8bd2e0847f875ff8325d18949d776f2a84a45d9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:03 +0100 Subject: [PATCH 347/733] New translations app.json (Finnish) --- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 14682e8e8..e70326bf2 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Koti", - "search": "Haku", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "Profiili" }, From a2b0e3e958c1ea098396a60b34b8499bd21747f8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:05 +0100 Subject: [PATCH 348/733] New translations app.json (Italian) --- .../StringsConvertor/input/it.lproj/app.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 20a1cbf47..f7066a707 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inizio", - "search": "Cerca", + "search_and_explore": "Search and Explore", "notifications": "Notifiche", "profile": "Profilo" }, @@ -159,7 +159,7 @@ "url": "URL", "mention": "Menzione", "link": "Collegamento", - "hashtag": "Etichetta", + "hashtag": "Hashtag", "email": "Email", "emoji": "Emoji" }, @@ -724,15 +724,15 @@ "title": "Segnalibri" }, "followed_tags": { - "title": "Followed Tags", + "title": "Etichette seguite", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "post", + "participants": "partecipanti", + "posts_today": "post di oggi" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Segui", + "unfollow": "Smetti di seguire" } } } From 21d231017d83903745878d19605ed7b9379eefc5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 21:53:06 +0100 Subject: [PATCH 349/733] New translations app.json (Hebrew) --- Localization/StringsConvertor/input/he.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 9517a2540..de337841c 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Home", - "search": "Search", + "search_and_explore": "Search and Explore", "notifications": "Notifications", "profile": "פרופיל" }, From e5c2e9837992cd7270ff1023e16b05f531c00e71 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:00 +0100 Subject: [PATCH 350/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 9453cb422..6825c1094 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Domov", - "search_and_explore": "Search and Explore", + "search_and_explore": "Poišči in razišči", "notifications": "Obvestila", "profile": "Profil" }, From ed69bb44f950d8ff4af1eb1bbc5b757456976bd1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:01 +0100 Subject: [PATCH 351/733] New translations app.json (Swedish) --- .../StringsConvertor/input/sv.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index a5393aa4b..cf8abbca5 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Hem", - "search_and_explore": "Search and Explore", + "search_and_explore": "Sök och utforska", "notifications": "Notiser", "profile": "Profil" }, @@ -724,15 +724,15 @@ "title": "Bokmärken" }, "followed_tags": { - "title": "Followed Tags", + "title": "Följda hashtaggar", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "inlägg", + "participants": "deltagare", + "posts_today": "inlägg idag" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Följ", + "unfollow": "Avfölj" } } } From 24d3620a935e28294df8cb0a38b7065103012388 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:02 +0100 Subject: [PATCH 352/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 8d2643a3f..f70dc116a 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "الرَّئِيسَة", - "search_and_explore": "Search and Explore", + "search_and_explore": "البَحث وَالاِستِكشاف", "notifications": "الإشعارات", "profile": "المِلَفُّ التَّعريفِيّ" }, From e57aa8587e8d7d4ef6d861d8117ae4041cf1767d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:03 +0100 Subject: [PATCH 353/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 900feaa3e..84ae80bd5 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inici", - "search_and_explore": "Search and Explore", + "search_and_explore": "Cerca i Explora", "notifications": "Notificacions", "profile": "Perfil" }, From c77b56a1af4ee1bd7380bf9bed61241b4211c557 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:04 +0100 Subject: [PATCH 354/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index f7066a707..dedc71b8c 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inizio", - "search_and_explore": "Search and Explore", + "search_and_explore": "Cerca ed Esplora", "notifications": "Notifiche", "profile": "Profilo" }, From e38cf441f193840f8e2bdcb8a6673b1895b4f78e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:06 +0100 Subject: [PATCH 355/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 722ac04e6..860d084da 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Principal", - "search_and_explore": "Search and Explore", + "search_and_explore": "Buscar y explorar", "notifications": "Notificaciones", "profile": "Perfil" }, From b39259cf8f57c6cf5aebee8ab2a3b3d41798bd88 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 1 Dec 2022 22:52:07 +0100 Subject: [PATCH 356/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index bf9439aa9..d9c36e449 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Heim", - "search_and_explore": "Search and Explore", + "search_and_explore": "Leita og kanna", "notifications": "Tilkynningar", "profile": "Notandasnið" }, From f3d5112d5f8ae011076a521646a35a5c181e5ad5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 02:41:36 +0100 Subject: [PATCH 357/733] New translations app.json (Korean) --- .../StringsConvertor/input/ko.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index d964670a9..dfe94cd69 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -724,15 +724,15 @@ "title": "Bookmarks" }, "followed_tags": { - "title": "Followed Tags", + "title": "팔로우한 태그", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "게시물", + "participants": "참가자", + "posts_today": "오늘" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "팔로우", + "unfollow": "팔로우 해제" } } } From 5f1f4ac5b4309c1198433edc204f10d7a7c5c6ce Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 07:56:17 +0100 Subject: [PATCH 358/733] New translations app.json (Vietnamese) --- .../StringsConvertor/input/vi.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 5cc1d3018..f0454707a 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Bảng tin", - "search_and_explore": "Search and Explore", + "search_and_explore": "Tìm và Khám Phá", "notifications": "Thông báo", "profile": "Trang hồ sơ" }, @@ -724,15 +724,15 @@ "title": "Tút đã lưu" }, "followed_tags": { - "title": "Followed Tags", + "title": "Hashtag Theo Dõi", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "tút", + "participants": "người thảo luận", + "posts_today": "tút hôm nay" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Theo dõi", + "unfollow": "Ngưng theo dõi" } } } From 9f29f7dd709189471a8f2ca71c9a927a461135d4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 07:56:18 +0100 Subject: [PATCH 359/733] New translations app.json (Galician) --- .../StringsConvertor/input/gl.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index a2af2e2b2..6d838cd06 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Inicio", - "search_and_explore": "Search and Explore", + "search_and_explore": "Buscar e Explorar", "notifications": "Notificacións", "profile": "Perfil" }, @@ -724,15 +724,15 @@ "title": "Marcadores" }, "followed_tags": { - "title": "Followed Tags", + "title": "Cancelos seguidos", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "publicacións", + "participants": "participantes", + "posts_today": "publicacións de hoxe" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Seguir", + "unfollow": "Deixar de seguir" } } } From c77fa949187871cf68bc6866e84481090f8962e4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 08:53:18 +0100 Subject: [PATCH 360/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 768e9c167..a48ff9cea 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Serrûpel", - "search_and_explore": "Search and Explore", + "search_and_explore": "Bigere û vekole", "notifications": "Agahdarî", "profile": "Profîl" }, From c92468a70615a5a371c93637085870afb89c81b8 Mon Sep 17 00:00:00 2001 From: David Godfrey Date: Fri, 2 Dec 2022 08:29:30 +0000 Subject: [PATCH 361/733] fix: Tidy up accessibility labels in bio fields Enables reading out the label for the checkmark, and avoids describing the title text as a 'button'. --- .../Profile/About/Cell/ProfileFieldCollectionViewCell.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift b/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift index 1ed76a485..068da2ed5 100644 --- a/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift +++ b/Mastodon/Scene/Profile/About/Cell/ProfileFieldCollectionViewCell.swift @@ -68,6 +68,11 @@ extension ProfileFieldCollectionViewCell { checkmark.addInteraction(editMenuInteraction) } + // Setup Accessibility + checkmark.isAccessibilityElement = true + checkmark.accessibilityTraits = .none + keyMetaLabel.accessibilityTraits = .none + // containerStackView: V - [ metaContainer | plainContainer ] let containerStackView = UIStackView() containerStackView.axis = .vertical From a6ff6e7cec0f160dd8eee953bac8e638400d171d Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 2 Dec 2022 11:06:15 +0100 Subject: [PATCH 362/733] chore: Update localizable strings for follow tags --- .../StringsConvertor/input/Base.lproj/app.json | 13 +++++++++++++ .../MastodonLocalization/Generated/Strings.swift | 8 ++++---- .../Resources/Base.lproj/Localizable.strings | 14 +++++++------- .../Resources/en.lproj/Localizable.strings | 8 +------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index df1a45fe1..c4a701948 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -722,6 +722,19 @@ }, "bookmark": { "title": "Bookmarks" + + }, + "followed_tags": { + "title": "Followed Tags", + "header": { + "posts": "posts", + "participants": "participants", + "posts_today": "posts today" + }, + "actions": { + "follow": "Follow", + "unfollow": "Unfollow" + } } } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index a521cd0fb..bafed05f6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -637,10 +637,10 @@ public enum L10n { /// Followed Tags public static let title = L10n.tr("Localizable", "Scene.FollowedTags.Title", fallback: "Followed Tags") public enum Actions { - /// follow - public static let follow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Follow", fallback: "follow") - /// unfollow - public static let unfollow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Unfollow", fallback: "unfollow") + /// Follow + public static let follow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Follow", fallback: "Follow") + /// Unfollow + public static let unfollow = L10n.tr("Localizable", "Scene.FollowedTags.Actions.Unfollow", fallback: "Unfollow") } public enum Header { /// participants diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index f8cc50a36..5204a1176 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -229,14 +229,14 @@ uploaded to Mastodon."; "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Your Favorites"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; -"Scene.FollowedTags.Title" = "Followed Tags"; -"Scene.FollowedTags.Header.Posts" = "posts"; -"Scene.FollowedTags.Header.Participants" = "participants"; -"Scene.FollowedTags.Header.PostsToday" = "posts today"; -"Scene.FollowedTags.Actions.Follow" = "follow"; -"Scene.FollowedTags.Actions.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; @@ -467,4 +467,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 3d1f4c0a4..2a3f1efbf 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -231,12 +231,6 @@ uploaded to Mastodon."; "Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; -"Scene.FollowedTags.Title" = "Followed Tags"; -"Scene.FollowedTags.Header.Posts" = "posts"; -"Scene.FollowedTags.Header.Participants" = "participants"; -"Scene.FollowedTags.Header.PostsToday" = "posts today"; -"Scene.FollowedTags.Actions.Follow" = "follow"; -"Scene.FollowedTags.Actions.Unfollow" = "unfollow"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; @@ -467,4 +461,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file From 918c2883a3f1e3383a6e1716d5b68ae9d5d1197a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 11:09:48 +0100 Subject: [PATCH 363/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 31ecc8a9a..38a652ed1 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -724,15 +724,15 @@ "title": "Lesezeichen" }, "followed_tags": { - "title": "Followed Tags", + "title": "Gefolgte Hashtags", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "Posts", + "participants": "Teilnehmer*innen", + "posts_today": "Posts heute" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Folgen", + "unfollow": "Entfolgen" } } } From 284fe549b3e822d309c01900cc393a7d7e075bf1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 14:15:35 +0100 Subject: [PATCH 364/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 38a652ed1..ffdc32f92 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Startseite", - "search_and_explore": "Search and Explore", + "search_and_explore": "Suchen und Entdecken", "notifications": "Mitteilungen", "profile": "Profil" }, From 1cb06d5f0088a677e399935bc076bb413379b4bc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 17:34:59 +0100 Subject: [PATCH 365/733] New translations app.json (Chinese Traditional) --- .../StringsConvertor/input/zh-Hant.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 41840f45d..0a8ab8e2d 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "首頁", - "search_and_explore": "Search and Explore", + "search_and_explore": "搜尋與探索", "notifications": "通知", "profile": "個人檔案" }, @@ -724,15 +724,15 @@ "title": "書籤" }, "followed_tags": { - "title": "Followed Tags", + "title": "已跟隨主題標籤", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "嘟文", + "participants": "參與者", + "posts_today": "本日嘟文" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "跟隨", + "unfollow": "取消跟隨" } } } From f6d7e4a2093eb3f89568fa6568dc0c14cc014e09 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 2 Dec 2022 19:13:48 +0100 Subject: [PATCH 366/733] New translations app.json (French) --- .../StringsConvertor/input/fr.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 7c77c0967..c644965ee 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Accueil", - "search_and_explore": "Search and Explore", + "search_and_explore": "Rechercher et explorer", "notifications": "Notifications", "profile": "Profil" }, @@ -724,15 +724,15 @@ "title": "Favoris" }, "followed_tags": { - "title": "Followed Tags", + "title": "Tags suivis", "header": { - "posts": "posts", + "posts": "messages", "participants": "participants", - "posts_today": "posts today" + "posts_today": "messages aujourd'hui" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Suivre", + "unfollow": "Ne plus suivre" } } } From 52f5213990f61a3c4d7f8445667db3218cfcba1f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 15:54:02 -0500 Subject: [PATCH 367/733] Allow a little bit of variance from square for compact layout --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 6b3e00189..6b5a02da0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -184,9 +184,10 @@ private extension StatusCardControl { private extension Card { var layout: StatusCardControl.Layout { - return width == height || image == nil + let aspectRatio = CGFloat(width) / CGFloat(height) + return abs(aspectRatio - 1) < 0.05 || image == nil ? .compact - : .large(aspectRatio: CGFloat(width) / CGFloat(height)) + : .large(aspectRatio: aspectRatio) } } From 16a814a27c4df96e6a1a11bcdc84df93dbd3528e Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 16:02:05 -0500 Subject: [PATCH 368/733] Cap the height of the status card --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 6b5a02da0..6bc8d6789 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -144,6 +144,9 @@ public final class StatusCardControl: UIControl { // This priority is important or constraints break; // it still renders the card correctly. .priority(.defaultLow - 1), + // set a reasonable max height for very tall images + imageView.heightAnchor + .constraint(lessThanOrEqualToConstant: 400) ] case .compact: containerStackView.alignment = .center From 9affb0f6371fdca37954ef4af389726cb3b23df6 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 30 Nov 2022 16:38:31 +0100 Subject: [PATCH 369/733] feat: Implement `translatedContent` which can be used to replace the StatusView content --- Mastodon.xcodeproj/project.pbxproj | 4 +++ .../Provider/DataSourceFacade+Status.swift | 6 ++++ .../Provider/DataSourceFacade+Translate.swift | 24 +++++++++++++++ .../TableviewCell/StatusTableViewCell.swift | 8 +++++ .../StatusThreadRootTableViewCell.swift | 8 +++++ .../Entity/Mastodon/Status.swift | 2 ++ .../Content/NotificationView+ViewModel.swift | 14 +++++++-- .../View/Content/StatusAuthorView.swift | 9 ++++++ .../Content/StatusView+Configuration.swift | 30 +++++++++++++++++++ .../View/Content/StatusView+ViewModel.swift | 26 +++++++++++----- .../MastodonUI/View/Content/StatusView.swift | 10 +++++++ .../MastodonUI/View/Menu/MastodonMenu.swift | 18 +++++++++++ 12 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 96404cebb..332c73f2d 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */; }; 2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; + 2AB12E4629362F27006BC925 /* DataSourceFacade+Translate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */; }; 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; }; 2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; }; 2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198648261C0B8500F0B013 /* SearchResultSection.swift */; }; @@ -535,6 +536,7 @@ 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderView.swift; sourceTree = ""; }; 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderViewActionButton.swift; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; + 2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Translate.swift"; sourceTree = ""; }; 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SFSymbols.swift"; sourceTree = ""; }; 2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; }; 2D198648261C0B8500F0B013 /* SearchResultSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultSection.swift; sourceTree = ""; }; @@ -2120,6 +2122,7 @@ DB63F74627990B0600455B82 /* DataSourceFacade+Hashtag.swift */, DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */, DB159C2A27A17BAC0068DC77 /* DataSourceFacade+Media.swift */, + 2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */, DB697DD5278F4C29004EF2F7 /* DataSourceProvider.swift */, DB697DDA278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift */, DB023D2927A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift */, @@ -3286,6 +3289,7 @@ DBF1572F27046F1A00EC00B7 /* SecondaryPlaceholderViewController.swift in Sources */, 2D4AD8A826316D3500613EFC /* SelectedAccountItem.swift in Sources */, DBE3CDFB261C6CA500430CC6 /* FavoriteViewModel.swift in Sources */, + 2AB12E4629362F27006BC925 /* DataSourceFacade+Translate.swift in Sources */, DBE3CE01261D623D00430CC6 /* FavoriteViewModel+State.swift in Sources */, 2D82BA0525E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift in Sources */, 2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */, diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index ac9da6e81..9d83d1073 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -393,6 +393,12 @@ extension DataSourceFacade { alertController.addAction(cancelAction) dependency.present(alertController, animated: true) + case let .translateStatus(translationContext): + guard let status = menuContext.status else { return } + try await DataSourceFacade.translateStatus( + provider: dependency, + status: status + ) } } // end func } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift new file mode 100644 index 000000000..61e836ed2 --- /dev/null +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -0,0 +1,24 @@ +// +// DataSourceFacade+Translate.swift +// Mastodon +// +// Created by Marcus Kida on 29.11.22. +// + +import UIKit +import CoreData +import CoreDataStack +import MastodonCore + +extension DataSourceFacade { + public static func translateStatus( + provider: UIViewController & NeedsDependency & AuthContextProvider, + status: ManagedObjectRecord + ) async throws { + let selectionFeedbackGenerator = await UISelectionFeedbackGenerator() + await selectionFeedbackGenerator.selectionChanged() + + let status = status.object(in: provider.context.managedObjectContext) + status?.translatedContent = "LOREM IPSUM TRANSLATED TEXT" + } +} diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift index c9850a0d3..3bb57302a 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift @@ -86,6 +86,14 @@ extension StatusTableViewCell { self.accessibilityLabel = accessibilityLabel } .store(in: &_disposeBag) + + statusView.viewModel + .$isTranslated + .receive(on: DispatchQueue.main) + .sink(receiveValue: { [weak self] _ in + self?.invalidateIntrinsicContentSize() + }) + .store(in: &_disposeBag) } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift index 350bf8660..5cc6f6596 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift @@ -81,6 +81,14 @@ extension StatusThreadRootTableViewCell { // a11y statusView.contentMetaText.textView.isAccessibilityElement = true statusView.contentMetaText.textView.isSelectable = true + + statusView.viewModel + .$isTranslated + .receive(on: DispatchQueue.main) + .sink(receiveValue: { [weak self] _ in + self?.invalidateIntrinsicContentSize() + }) + .store(in: &disposeBag) } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift index 0c7291913..1f46a6ce1 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift @@ -99,6 +99,8 @@ public final class Status: NSManagedObject { @NSManaged public private(set) var deletedAt: Date? // sourcery: autoUpdatableObject @NSManaged public private(set) var revealedAt: Date? + + @Published public var translatedContent: String? } extension Status { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index 714cf676d..11039875a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -37,6 +37,7 @@ extension NotificationView { @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false + @Published public var isTranslated = false @Published public var timestamp: Date? @@ -203,20 +204,27 @@ extension NotificationView.ViewModel { $authorName, $isMuting, $isBlocking, - $isMyself + Publishers.CombineLatest( + $isMyself, + $isTranslated + ) ) - .sink { authorName, isMuting, isBlocking, isMyself in + .sink { authorName, isMuting, isBlocking, comb2 in guard let name = authorName?.string else { notificationView.menuButton.menu = nil return } + let (isMyself, isTranslated) = comb2 + let menuContext = NotificationView.AuthorMenuContext( name: name, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself, - isBookmarking: false // no bookmark action display for notification item + isBookmarking: false, // no bookmark action display for notification item + isTranslated: isTranslated, + statusLanguage: "" ) let (menu, actions) = notificationView.setupAuthorMenu(menuContext: menuContext) notificationView.menuButton.menu = menu diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index 0631875c0..c930a7b66 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -149,12 +149,21 @@ extension StatusAuthorView { public let isBlocking: Bool public let isMyself: Bool public let isBookmarking: Bool + + public let isTranslated: Bool + public let statusLanguage: String? } public func setupAuthorMenu(menuContext: AuthorMenuContext) -> (UIMenu, [UIAccessibilityCustomAction]) { var actions = [MastodonMenu.Action]() if !menuContext.isMyself { + if let statusLanguage = menuContext.statusLanguage, !menuContext.isTranslated { + actions.append( + .translateStatus(.init(language: statusLanguage)) + ) + } + actions.append(contentsOf: [ .muteUser(.init( name: menuContext.name, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 47e4f18ff..b562e40dc 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -55,6 +55,14 @@ extension StatusView { configurePoll(status: status) configureToolbar(status: status) configureFilter(status: status) + + status.$translatedContent + .receive(on: DispatchQueue.main) + .compactMap { $0 } + .sink { [weak self] _ in + self?.configureTranslated(status: status) + } + .store(in: &disposeBag) } } @@ -231,7 +239,28 @@ extension StatusView { .store(in: &disposeBag) } + func configureTranslated(status: Status) { + guard + let translatedContent = status.translatedContent + else { return } + + // content + do { + let content = MastodonContent(content: translatedContent, emojis: status.emojis.asDictionary) + let metaContent = try MastodonMetaContent.convert(document: content) + viewModel.content = metaContent + viewModel.isTranslated = true + } catch { + assertionFailure(error.localizedDescription) + viewModel.content = PlaintextMetaContent(string: "") + } + } + private func configureContent(status: Status) { + guard status.translatedContent == nil else { + return configureTranslated(status: status) + } + let status = status.reblog ?? status // spoilerText @@ -254,6 +283,7 @@ extension StatusView { let content = MastodonContent(content: status.content, emojis: status.emojis.asDictionary) let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent + viewModel.isTranslated = false } catch { assertionFailure(error.localizedDescription) viewModel.content = PlaintextMetaContent(string: "") diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 21ce0ae74..b56bba2e1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -17,6 +17,7 @@ import MastodonCommon import MastodonExtension import MastodonLocalization import MastodonSDK +import MastodonMeta extension StatusView { public final class ViewModel: ObservableObject { @@ -27,7 +28,8 @@ extension StatusView { let logger = Logger(subsystem: "StatusView", category: "ViewModel") public var authContext: AuthContext? - + public var originalStatus: Status? + // Header @Published public var header: Header = .none @@ -42,6 +44,7 @@ extension StatusView { @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false + @Published public var isTranslated = false @Published public var timestamp: Date? public var timestampFormatter: ((_ date: Date) -> String)? @@ -134,12 +137,13 @@ extension StatusView { isContentSensitive = false isMediaSensitive = false isSensitiveToggled = false + isTranslated = false activeFilters = [] filterContext = nil } - init() { + init() { // isReblogEnabled Publishers.CombineLatest( $visibility, @@ -581,15 +585,21 @@ extension StatusView.ViewModel { $isBlocking, $isBookmark ) + let publishersThree = Publishers.CombineLatest( + $isTranslated, + $language + ) - Publishers.CombineLatest( + Publishers.CombineLatest3( publisherOne.eraseToAnyPublisher(), - publishersTwo.eraseToAnyPublisher() + publishersTwo.eraseToAnyPublisher(), + publishersThree.eraseToAnyPublisher() ).eraseToAnyPublisher() - .sink { tupleOne, tupleTwo in + .sink { tupleOne, tupleTwo, tupleThree in let (authorName, isMyself) = tupleOne let (isMuting, isBlocking, isBookmark) = tupleTwo - + let (isTranslated, language) = tupleThree + guard let name = authorName?.string else { statusView.authorView.menuButton.menu = nil return @@ -600,7 +610,9 @@ extension StatusView.ViewModel { isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself, - isBookmarking: isBookmark + isBookmarking: isBookmark, + isTranslated: isTranslated, + statusLanguage: language ) let (menu, actions) = authorView.setupAuthorMenu(menuContext: menuContext) authorView.menuButton.menu = menu diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 30f62eaf7..bd901b08a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -275,6 +275,16 @@ extension StatusView { // statusMetricView statusMetricView.delegate = self + + // status translation + viewModel.$isTranslated.sink { [weak self] isTranslated in + guard + let self = self, + let status = self.viewModel.originalStatus + else { return } + self.configureTranslated(status: status) + } + .store(in: &disposeBag) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index 422494328..e2e887db3 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -40,6 +40,7 @@ public enum MastodonMenu { extension MastodonMenu { public enum Action { + case translateStatus(TranslateStatusActionContext) case muteUser(MuteUserActionContext) case blockUser(BlockUserActionContext) case reportUser(ReportUserActionContext) @@ -126,6 +127,15 @@ extension MastodonMenu { delegate.menuAction(self) } return deleteAction + case let .translateStatus(context): + let translateAction = BuiltAction( + title: String(format: "Translate from %@", context.language), + image: UIImage(systemName: "character.book.closed") + ) { [weak delegate] in + guard let delegate = delegate else { return } + delegate.menuAction(self) + } + return translateAction } // end switch } // end func build } // end enum Action @@ -225,4 +235,12 @@ extension MastodonMenu { self.showReblogs = showReblogs } } + + public struct TranslateStatusActionContext { + public let language: String + + public init(language: String) { + self.language = language + } + } } From d5be87992df0c176335562a5ae1985e466c67f8b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 2 Dec 2022 12:12:46 +0100 Subject: [PATCH 370/733] feat: Implement /translate endpoint --- .../Provider/DataSourceFacade+Translate.swift | 16 ++++++- .../API/APIService+Status+Translate.swift | 34 +++++++++++++ .../API/Mastodon+API+Statuses+Translate.swift | 48 +++++++++++++++++++ .../Entity/Mastodon+Entity+Translation.swift | 22 +++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index 61e836ed2..f2d439cf6 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -18,7 +18,19 @@ extension DataSourceFacade { let selectionFeedbackGenerator = await UISelectionFeedbackGenerator() await selectionFeedbackGenerator.selectionChanged() - let status = status.object(in: provider.context.managedObjectContext) - status?.translatedContent = "LOREM IPSUM TRANSLATED TEXT" + guard + let status = status.object(in: provider.context.managedObjectContext) + else { + return + } + + let result = try await provider.context + .apiService + .translateStatus( + statusID: status.id, + authenticationBox: provider.authContext.mastodonAuthenticationBox + ).value + + status.translatedContent = result.content } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift new file mode 100644 index 000000000..a802d6489 --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Status+Translate.swift @@ -0,0 +1,34 @@ +// +// APIService+Status+Translate.swift +// Mastodon +// +// Created by Marcus Kida on 02.12.2022. +// + +import Foundation +import Combine +import CoreData +import CoreDataStack +import CommonOSLog +import MastodonSDK + +extension APIService { + + public func translateStatus( + statusID: Mastodon.Entity.Status.ID, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content { + let domain = authenticationBox.domain + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Statuses.translate( + session: session, + domain: domain, + statusID: statusID, + authorization: authorization + ).singleOutput() + + return response + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift new file mode 100644 index 000000000..c3e790b67 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+Translate.swift @@ -0,0 +1,48 @@ +// +// Mastodon+API+Statuses+Translate.swift +// +// +// Created by Marcus Kida on 02.12.2022. +// + +import Foundation +import Combine + +extension Mastodon.API.Statuses { + + private static func translateEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("statuses") + .appendingPathComponent(statusID) + .appendingPathComponent("translate") + } + + /// Translate Status + /// + /// Translate a given Status. + /// + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - statusID: id for status + /// - authorization: User token. Could be nil if status is public + /// - Returns: `AnyPublisher` contains `Status` nested in the response + public static func translate( + session: URLSession, + domain: String, + statusID: Mastodon.Entity.Status.ID, + authorization: Mastodon.API.OAuth.Authorization? + ) -> AnyPublisher, Error> { + let request = Mastodon.API.post( + url: translateEndpointURL(domain: domain, statusID: statusID), + query: nil, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Translation.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift new file mode 100644 index 000000000..b8993de9e --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Marcus Kida on 02.12.22. +// + +import Foundation + +extension Mastodon.Entity { + public struct Translation: Codable { + public let content: String? + public let sourceLanguage: String? + public let provider: String? + + enum CodingKeys: String, CodingKey { + case content + case sourceLanguage = "detected_source_language" + case provider + } + } +} From ac76e7f4355d20e6b9707955a0ee34ac9a2c5481 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 2 Dec 2022 14:42:50 +0100 Subject: [PATCH 371/733] feat: Implement translation of reposts --- .../Provider/DataSourceFacade+Translate.swift | 21 ++++++++++++------ .../Content/StatusView+Configuration.swift | 22 +++++++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index f2d439cf6..08557a4bf 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -24,13 +24,20 @@ extension DataSourceFacade { return } - let result = try await provider.context - .apiService - .translateStatus( - statusID: status.id, - authenticationBox: provider.authContext.mastodonAuthenticationBox - ).value + func translate(status: Status) async throws -> String? { + let value = try await provider.context + .apiService + .translateStatus( + statusID: status.id, + authenticationBox: provider.authContext.mastodonAuthenticationBox + ).value + return value.content + } - status.translatedContent = result.content + if let reblog = status.reblog { + reblog.translatedContent = try await translate(status: reblog) + } else { + status.translatedContent = try await translate(status: status) + } } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index b562e40dc..498b77a5f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -63,6 +63,14 @@ extension StatusView { self?.configureTranslated(status: status) } .store(in: &disposeBag) + + status.reblog?.$translatedContent + .receive(on: DispatchQueue.main) + .compactMap { $0 } + .sink { [weak self] _ in + self?.configureTranslated(status: status) + } + .store(in: &disposeBag) } } @@ -240,9 +248,19 @@ extension StatusView { } func configureTranslated(status: Status) { + let translatedContent: String? = { + if let translatedContent = status.reblog?.translatedContent { + return translatedContent + } + return status.translatedContent + + }() + guard - let translatedContent = status.translatedContent - else { return } + let translatedContent = translatedContent + else { + return + } // content do { From 1c5b66f7e715a31c167289d468981d25899160a8 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 20:35:11 -0500 Subject: [PATCH 372/733] Embed a web view for viewing content inline --- .../CoreData 5.xcdatamodel/contents | 3 +- .../CoreDataStack/Entity/Mastodon/Card.swift | 8 ++- .../Persistence/Persistence+Card.swift | 3 +- .../Sources/MastodonExtension/UIView.swift | 18 ++++-- .../View/Content/StatusCardControl.swift | 64 ++++++++++++++++++- .../View/Content/StatusView+ViewModel.swift | 6 ++ 6 files changed, 91 insertions(+), 11 deletions(-) diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents index c18d7492b..4d44775e1 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 5.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -14,6 +14,7 @@ + diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift index d656191f9..64f5e2120 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Card.swift @@ -49,6 +49,8 @@ public final class Card: NSManagedObject { @NSManaged public private(set) var embedURLRaw: String? // sourcery: autoGenerateProperty @NSManaged public private(set) var blurhash: String? + // sourcery: autoGenerateProperty + @NSManaged public private(set) var html: String? // sourcery: autoGenerateRelationship @NSManaged public private(set) var status: Status @@ -96,6 +98,7 @@ extension Card: AutoGenerateProperty { public let image: String? public let embedURLRaw: String? public let blurhash: String? + public let html: String? public init( urlRaw: String, @@ -110,7 +113,8 @@ extension Card: AutoGenerateProperty { height: Int64, image: String?, embedURLRaw: String?, - blurhash: String? + blurhash: String?, + html: String? ) { self.urlRaw = urlRaw self.title = title @@ -125,6 +129,7 @@ extension Card: AutoGenerateProperty { self.image = image self.embedURLRaw = embedURLRaw self.blurhash = blurhash + self.html = html } } @@ -142,6 +147,7 @@ extension Card: AutoGenerateProperty { self.image = property.image self.embedURLRaw = property.embedURLRaw self.blurhash = property.blurhash + self.html = property.html } public func update(property: Property) { diff --git a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift index 838d5e128..9ab8a817c 100644 --- a/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift +++ b/MastodonSDK/Sources/MastodonCore/Persistence/Persistence+Card.swift @@ -77,7 +77,8 @@ extension Persistence.Card { height: Int64(context.entity.height ?? 0), image: context.entity.image, embedURLRaw: context.entity.embedURL, - blurhash: context.entity.blurhash + blurhash: context.entity.blurhash, + html: context.entity.html.flatMap { $0.isEmpty ? nil : $0 } ) let card = Card.insert( diff --git a/MastodonSDK/Sources/MastodonExtension/UIView.swift b/MastodonSDK/Sources/MastodonExtension/UIView.swift index fa62be6c0..bfa253680 100644 --- a/MastodonSDK/Sources/MastodonExtension/UIView.swift +++ b/MastodonSDK/Sources/MastodonExtension/UIView.swift @@ -48,18 +48,22 @@ extension UIView { } public extension UIView { - - func pinToParent() { + + @discardableResult + func pinToParent() -> [NSLayoutConstraint] { pinTo(to: self.superview) } - - func pinTo(to view: UIView?) { - guard let pinToView = view else { return } - NSLayoutConstraint.activate([ + + @discardableResult + func pinTo(to view: UIView?) -> [NSLayoutConstraint] { + guard let pinToView = view else { return [] } + let constraints = [ topAnchor.constraint(equalTo: pinToView.topAnchor), leadingAnchor.constraint(equalTo: pinToView.leadingAnchor), trailingAnchor.constraint(equalTo: pinToView.trailingAnchor), bottomAnchor.constraint(equalTo: pinToView.bottomAnchor), - ]) + ] + NSLayoutConstraint.activate(constraints) + return constraints } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 6bc8d6789..7a63441e9 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -11,8 +11,11 @@ import MastodonAsset import MastodonCore import CoreDataStack import UIKit +import WebKit public final class StatusCardControl: UIControl { + public var urlToOpen = PassthroughSubject() + private var disposeBag = Set() private let containerStackView = UIStackView() @@ -23,6 +26,9 @@ public final class StatusCardControl: UIControl { private let titleLabel = UILabel() private let linkLabel = UILabel() + private static let cardContentPool = WKProcessPool() + private var webView: WKWebView? + private var layout: Layout? private var layoutConstraints: [NSLayoutConstraint] = [] @@ -115,6 +121,12 @@ public final class StatusCardControl: UIControl { self?.containerStackView.layoutIfNeeded() } + if let html = card.html, !html.isEmpty { + let webView = setupWebView() + webView.loadHTMLString("" + html, baseURL: nil) + addSubview(webView) + } + updateConstraints(for: card.layout) } @@ -123,6 +135,9 @@ public final class StatusCardControl: UIControl { if let window = window { layer.borderWidth = 1 / window.screen.scale + } else { + webView?.removeFromSuperview() + webView = nil } } @@ -159,6 +174,10 @@ public final class StatusCardControl: UIControl { ] } + if let webView { + layoutConstraints += webView.pinTo(to: imageView) + } + NSLayoutConstraint.activate(layoutConstraints) } @@ -178,6 +197,46 @@ public final class StatusCardControl: UIControl { } } +extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { + fileprivate func setupWebView() -> WKWebView { + let config = WKWebViewConfiguration() + config.processPool = Self.cardContentPool + config.websiteDataStore = .nonPersistent() // private/incognito mode + config.suppressesIncrementalRendering = true + config.allowsInlineMediaPlayback = true + let webView = WKWebView(frame: .zero, configuration: config) + webView.uiDelegate = self + webView.navigationDelegate = self + webView.translatesAutoresizingMaskIntoConstraints = false + self.webView = webView + return webView + } + + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy { + let isTopLevelNavigation: Bool + if let frame = navigationAction.targetFrame { + isTopLevelNavigation = frame.isMainFrame + } else { + isTopLevelNavigation = true + } + + if isTopLevelNavigation, + // ignore form submits and such + navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .other, + let url = navigationAction.request.url, + url.absoluteString != "about:blank" { + urlToOpen.send(url) + return .cancel + } + return .allow + } + + public func webViewDidClose(_ webView: WKWebView) { + webView.removeFromSuperview() + self.webView = nil + } +} + private extension StatusCardControl { enum Layout: Equatable { case compact @@ -187,7 +246,10 @@ private extension StatusCardControl { private extension Card { var layout: StatusCardControl.Layout { - let aspectRatio = CGFloat(width) / CGFloat(height) + var aspectRatio = CGFloat(width) / CGFloat(height) + if !aspectRatio.isFinite { + aspectRatio = 1 + } return abs(aspectRatio - 1) < 0.05 || image == nil ? .compact : .large(aspectRatio: aspectRatio) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 77de106b1..634473a65 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -494,6 +494,12 @@ extension StatusView.ViewModel { statusView.setStatusCardControlDisplay() } .store(in: &disposeBag) + + statusView.statusCardControl.urlToOpen + .sink { url in + statusView.delegate?.statusView(statusView, didTapCardWithURL: url) + } + .store(in: &disposeBag) } private func bindToolbar(statusView: StatusView) { From a29e88b60be224d102aa48be6bf4c63a457139c9 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 22:10:35 -0500 Subject: [PATCH 373/733] Fix web view reuse --- .../MastodonUI/View/Content/StatusCardControl.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 7a63441e9..6ed7f48c5 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -125,6 +125,9 @@ public final class StatusCardControl: UIControl { let webView = setupWebView() webView.loadHTMLString("" + html, baseURL: nil) addSubview(webView) + } else { + webView?.removeFromSuperview() + webView = nil } updateConstraints(for: card.layout) @@ -135,9 +138,6 @@ public final class StatusCardControl: UIControl { if let window = window { layer.borderWidth = 1 / window.screen.scale - } else { - webView?.removeFromSuperview() - webView = nil } } @@ -199,6 +199,8 @@ public final class StatusCardControl: UIControl { extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { fileprivate func setupWebView() -> WKWebView { + if let webView { return webView } + let config = WKWebViewConfiguration() config.processPool = Self.cardContentPool config.websiteDataStore = .nonPersistent() // private/incognito mode From 946d47abdd9eed610fe547f2ff3ec006139234e3 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 22:35:18 -0500 Subject: [PATCH 374/733] Fix highlight behavior --- .../MastodonUI/View/Content/StatusCardControl.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 6ed7f48c5..bffa56f0f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -33,7 +33,15 @@ public final class StatusCardControl: UIControl { private var layoutConstraints: [NSLayoutConstraint] = [] public override var isHighlighted: Bool { - didSet { highlightView.isHidden = !isHighlighted } + didSet { + // override UIKit behavior of highlighting subviews when cell is highlighted + if isHighlighted, + let cell = sequence(first: self, next: \.superview).first(where: { $0 is UITableViewCell }) as? UITableViewCell { + highlightView.isHidden = cell.isHighlighted + } else { + highlightView.isHidden = !isHighlighted + } + } } public override init(frame: CGRect) { @@ -53,7 +61,7 @@ public final class StatusCardControl: UIControl { maximumContentSizeCategory = .accessibilityLarge } - highlightView.backgroundColor = UIColor.black.withAlphaComponent(0.1) + highlightView.backgroundColor = UIColor.label.withAlphaComponent(0.1) highlightView.isHidden = true titleLabel.numberOfLines = 2 From 5932d00f2fba696a856cc1eb5d088477ced5fd4b Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 22:55:16 -0500 Subject: [PATCH 375/733] add a divider between the image and the text in the card --- .../MastodonExtension/NSLayoutConstraint.swift | 12 ++++++++++++ .../MastodonUI/View/Content/StatusCardControl.swift | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonExtension/NSLayoutConstraint.swift b/MastodonSDK/Sources/MastodonExtension/NSLayoutConstraint.swift index 057b17859..3251eb58b 100644 --- a/MastodonSDK/Sources/MastodonExtension/NSLayoutConstraint.swift +++ b/MastodonSDK/Sources/MastodonExtension/NSLayoutConstraint.swift @@ -17,4 +17,16 @@ extension NSLayoutConstraint { self.identifier = identifier return self } + + @discardableResult + public func activate() -> Self { + self.isActive = true + return self + } + + @discardableResult + public func deactivate() -> Self { + self.isActive = false + return self + } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index bffa56f0f..dc8efc6c0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -22,6 +22,7 @@ public final class StatusCardControl: UIControl { private let labelStackView = UIStackView() private let highlightView = UIView() + private let dividerView = UIView() private let imageView = UIImageView() private let titleLabel = UILabel() private let linkLabel = UILabel() @@ -31,6 +32,7 @@ public final class StatusCardControl: UIControl { private var layout: Layout? private var layoutConstraints: [NSLayoutConstraint] = [] + private var dividerConstraint: NSLayoutConstraint? public override var isHighlighted: Bool { didSet { @@ -88,6 +90,7 @@ public final class StatusCardControl: UIControl { labelStackView.spacing = 2 containerStackView.addArrangedSubview(imageView) + containerStackView.addArrangedSubview(dividerView) containerStackView.addArrangedSubview(labelStackView) containerStackView.isUserInteractionEnabled = false containerStackView.distribution = .fill @@ -146,6 +149,7 @@ public final class StatusCardControl: UIControl { if let window = window { layer.borderWidth = 1 / window.screen.scale + dividerConstraint?.constant = 1 / window.screen.scale } } @@ -154,7 +158,9 @@ public final class StatusCardControl: UIControl { self.layout = layout NSLayoutConstraint.deactivate(layoutConstraints) + dividerConstraint?.deactivate() + let pixelSize = 1 / (window?.screen.scale ?? 1) switch layout { case .large(let aspectRatio): containerStackView.alignment = .fill @@ -169,8 +175,9 @@ public final class StatusCardControl: UIControl { .priority(.defaultLow - 1), // set a reasonable max height for very tall images imageView.heightAnchor - .constraint(lessThanOrEqualToConstant: 400) + .constraint(lessThanOrEqualToConstant: 400), ] + dividerConstraint = dividerView.heightAnchor.constraint(equalToConstant: pixelSize).activate() case .compact: containerStackView.alignment = .center containerStackView.axis = .horizontal @@ -178,8 +185,9 @@ public final class StatusCardControl: UIControl { imageView.heightAnchor.constraint(equalTo: heightAnchor), imageView.widthAnchor.constraint(equalToConstant: 85), heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1), - heightAnchor.constraint(greaterThanOrEqualToConstant: 85) + heightAnchor.constraint(greaterThanOrEqualToConstant: 85), ] + dividerConstraint = dividerView.widthAnchor.constraint(equalToConstant: pixelSize).activate() } if let webView { @@ -201,6 +209,7 @@ public final class StatusCardControl: UIControl { private func apply(theme: Theme) { layer.borderColor = theme.separator.cgColor + dividerView.backgroundColor = theme.separator imageView.backgroundColor = theme.systemElevatedBackgroundColor } } From 7944ec6399894b546ddc6ca716a9a283cc274242 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 2 Dec 2022 23:29:14 -0500 Subject: [PATCH 376/733] Load embed web view only on tap (for privacy) --- .../View/Content/StatusCardControl.swift | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index dc8efc6c0..402763be3 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -26,6 +26,23 @@ public final class StatusCardControl: UIControl { private let imageView = UIImageView() private let titleLabel = UILabel() private let linkLabel = UILabel() + private lazy var showEmbedButton: UIButton = { + if #available(iOS 15.0, *) { + var configuration = UIButton.Configuration.gray() + configuration.background.visualEffect = UIBlurEffect(style: .systemUltraThinMaterial) + configuration.baseBackgroundColor = .clear + configuration.cornerStyle = .capsule + configuration.buttonSize = .large + return UIButton(configuration: configuration, primaryAction: UIAction { [weak self] _ in + self?.showWebView() + }) + } + + return UIButton(type: .system, primaryAction: UIAction { [weak self] _ in + self?.showWebView() + }) + }() + private var html = "" private static let cardContentPool = WKProcessPool() private var webView: WKWebView? @@ -95,14 +112,23 @@ public final class StatusCardControl: UIControl { containerStackView.isUserInteractionEnabled = false containerStackView.distribution = .fill + showEmbedButton.setImage(UIImage(systemName: "play.fill"), for: .normal) + addSubview(containerStackView) addSubview(highlightView) + addSubview(showEmbedButton) containerStackView.translatesAutoresizingMaskIntoConstraints = false highlightView.translatesAutoresizingMaskIntoConstraints = false + showEmbedButton.translatesAutoresizingMaskIntoConstraints = false containerStackView.pinToParent() highlightView.pinToParent() + NSLayoutConstraint.activate([ + showEmbedButton.widthAnchor.constraint(equalTo: showEmbedButton.heightAnchor), + showEmbedButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor), + showEmbedButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor), + ]) } required init?(coder: NSCoder) { @@ -133,12 +159,13 @@ public final class StatusCardControl: UIControl { } if let html = card.html, !html.isEmpty { - let webView = setupWebView() - webView.loadHTMLString("" + html, baseURL: nil) - addSubview(webView) + showEmbedButton.isHidden = false + self.html = html } else { webView?.removeFromSuperview() webView = nil + showEmbedButton.isHidden = true + self.html = "" } updateConstraints(for: card.layout) @@ -190,10 +217,6 @@ public final class StatusCardControl: UIControl { dividerConstraint = dividerView.widthAnchor.constraint(equalToConstant: pixelSize).activate() } - if let webView { - layoutConstraints += webView.pinTo(to: imageView) - } - NSLayoutConstraint.activate(layoutConstraints) } @@ -214,6 +237,15 @@ public final class StatusCardControl: UIControl { } } +extension StatusCardControl { + fileprivate func showWebView() { + let webView = setupWebView() + webView.loadHTMLString("" + html, baseURL: nil) + addSubview(webView) + webView.pinTo(to: imageView) + } +} + extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { fileprivate func setupWebView() -> WKWebView { if let webView { return webView } From c67e6ce45ec5f3a47576a5fc51deb1b4eec3622d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 11:27:51 -0500 Subject: [PATCH 377/733] Fix white flash in dark mode --- .../MastodonUI/View/Content/StatusCardControl.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 402763be3..c3945f630 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -241,8 +241,10 @@ extension StatusCardControl { fileprivate func showWebView() { let webView = setupWebView() webView.loadHTMLString("" + html, baseURL: nil) - addSubview(webView) - webView.pinTo(to: imageView) + if webView.superview == nil { + addSubview(webView) + webView.pinTo(to: imageView) + } } } @@ -259,6 +261,8 @@ extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { webView.uiDelegate = self webView.navigationDelegate = self webView.translatesAutoresizingMaskIntoConstraints = false + webView.isOpaque = false + webView.backgroundColor = .clear self.webView = webView return webView } From e46c25892dee5c58eb1805345d07998146e1ee7f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 11:29:03 -0500 Subject: [PATCH 378/733] =?UTF-8?q?Add=20label=20to=20the=20=E2=80=9Cload?= =?UTF-8?q?=20embed=E2=80=9D=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Localization/StringsConvertor/input/Base.lproj/app.json | 1 + Localization/app.json | 1 + .../Sources/MastodonLocalization/Generated/Strings.swift | 2 ++ .../Resources/Base.lproj/Localizable.strings | 1 + .../MastodonUI/View/Content/StatusCardControl.swift | 7 ++++--- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index ea046bfbc..e09ab983c 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -132,6 +132,7 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", "poll": { "vote": "Vote", "closed": "Closed" diff --git a/Localization/app.json b/Localization/app.json index ea046bfbc..e09ab983c 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -132,6 +132,7 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", "poll": { "vote": "Vote", "closed": "Closed" diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 0392d2b05..335638030 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -272,6 +272,8 @@ public enum L10n { public enum Status { /// Content Warning public static let contentWarning = L10n.tr("Localizable", "Common.Controls.Status.ContentWarning", fallback: "Content Warning") + /// Load Embed + 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") /// Sensitive Content diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index adeaad07b..3c3e16ca3 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -107,6 +107,7 @@ Please check your internet connection."; "Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; "Common.Controls.Status.Actions.Unreblog" = "Undo reblog"; "Common.Controls.Status.ContentWarning" = "Content Warning"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index c3945f630..376f54eb4 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -9,6 +9,7 @@ import AlamofireImage import Combine import MastodonAsset import MastodonCore +import MastodonLocalization import CoreDataStack import UIKit import WebKit @@ -33,6 +34,9 @@ public final class StatusCardControl: UIControl { configuration.baseBackgroundColor = .clear configuration.cornerStyle = .capsule configuration.buttonSize = .large + configuration.title = L10n.Common.Controls.Status.loadEmbed + configuration.image = UIImage(systemName: "play.fill") + configuration.imagePadding = 12 return UIButton(configuration: configuration, primaryAction: UIAction { [weak self] _ in self?.showWebView() }) @@ -112,8 +116,6 @@ public final class StatusCardControl: UIControl { containerStackView.isUserInteractionEnabled = false containerStackView.distribution = .fill - showEmbedButton.setImage(UIImage(systemName: "play.fill"), for: .normal) - addSubview(containerStackView) addSubview(highlightView) addSubview(showEmbedButton) @@ -125,7 +127,6 @@ public final class StatusCardControl: UIControl { containerStackView.pinToParent() highlightView.pinToParent() NSLayoutConstraint.activate([ - showEmbedButton.widthAnchor.constraint(equalTo: showEmbedButton.heightAnchor), showEmbedButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor), showEmbedButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor), ]) From 348e176f89fc4d3db2673cc86dfefd06c4d6479f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 11:30:21 -0500 Subject: [PATCH 379/733] slight code reorg --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 376f54eb4..51c125a87 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -238,7 +238,7 @@ public final class StatusCardControl: UIControl { } } -extension StatusCardControl { +extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { fileprivate func showWebView() { let webView = setupWebView() webView.loadHTMLString("" + html, baseURL: nil) @@ -247,10 +247,8 @@ extension StatusCardControl { webView.pinTo(to: imageView) } } -} -extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { - fileprivate func setupWebView() -> WKWebView { + private func setupWebView() -> WKWebView { if let webView { return webView } let config = WKWebViewConfiguration() From 3212e54bf52e482e232493efc6e706c13c22482f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 13:07:55 -0500 Subject: [PATCH 380/733] Fix generating relay delegate methods with return values --- .../AutoGenerateProtocolDelegate.swifttemplate | 16 +++++++++++++++- ...toGenerateProtocolRelayDelegate.swifttemplate | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Mastodon/Template/AutoGenerateProtocolDelegate.swifttemplate b/Mastodon/Template/AutoGenerateProtocolDelegate.swifttemplate index 47eb4ce19..e8677d970 100644 --- a/Mastodon/Template/AutoGenerateProtocolDelegate.swifttemplate +++ b/Mastodon/Template/AutoGenerateProtocolDelegate.swifttemplate @@ -1,3 +1,17 @@ +<% +func methodDeclaration(_ method: SourceryRuntime.Method, newName: String) -> String { + var result = newName + if method.throws { + result = result + " throws" + } else if method.rethrows { + result = result + " rethrows" + } + if method.returnTypeName.isVoid { + return result + } + return result + " -> \(method.returnTypeName)" +} +-%> <% for type in types.implementing["AutoGenerateProtocolDelegate"] { guard let replaceOf = type.annotations["replaceOf"] as? String else { continue } guard let replaceWith = type.annotations["replaceWith"] as? String else { continue } @@ -5,7 +19,7 @@ guard let aProtocol = types.protocols.first(where: { $0.name == protocolToGenerate }) else { continue } -%> // sourcery:inline:<%= type.name %>.AutoGenerateProtocolDelegate <% for method in aProtocol.methods { -%> -<%= method.name.replacingOccurrences(of: replaceOf, with: replaceWith) %> +<%= methodDeclaration(method, newName: method.name.replacingOccurrences(of: replaceOf, with: replaceWith)) %> <% } -%> // sourcery:end <% } %> diff --git a/Mastodon/Template/AutoGenerateProtocolRelayDelegate.swifttemplate b/Mastodon/Template/AutoGenerateProtocolRelayDelegate.swifttemplate index b57f26038..d2b0dd58c 100644 --- a/Mastodon/Template/AutoGenerateProtocolRelayDelegate.swifttemplate +++ b/Mastodon/Template/AutoGenerateProtocolRelayDelegate.swifttemplate @@ -6,6 +6,9 @@ func methodDeclaration(_ method: SourceryRuntime.Method) -> String { } else if method.rethrows { result = result + " rethrows" } + if method.returnTypeName.isVoid { + return result + } return result + " -> \(method.returnTypeName)" } -%> @@ -42,7 +45,7 @@ func methodCall( guard let aProtocol = types.protocols.first(where: { $0.name == protocolToGenerate }) else { continue } -%> // sourcery:inline:<%= type.name %>.AutoGenerateProtocolRelayDelegate <% for method in aProtocol.methods { -%> -func <%= method.name -%> { +func <%= methodDeclaration(method) -%> { <%= methodCall(method, replaceOf: replaceOf, replaceWith: replaceWith) %> } From ebf383540391ff8c3fbc3dae62545474688baf63 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 13:09:04 -0500 Subject: [PATCH 381/733] extract out StatusActivityItem class --- Mastodon.xcodeproj/project.pbxproj | 8 +++ Mastodon/Helper/ImageProvider.swift | 39 ++++++++++++ .../Helper/URLActivityItemWithMetadata.swift | 33 ++++++++++ .../Provider/DataSourceFacade+Status.swift | 62 ++++--------------- .../Scene/ShareViewController.swift | 3 +- 5 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 Mastodon/Helper/ImageProvider.swift create mode 100644 Mastodon/Helper/URLActivityItemWithMetadata.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 453027074..a970c5a61 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -89,6 +89,8 @@ 62FD27D12893707600B205C5 /* BookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D02893707600B205C5 /* BookmarkViewController.swift */; }; 62FD27D32893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D22893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift */; }; 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; }; + 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; + 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; @@ -602,6 +604,8 @@ 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.profile.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.profile.xcconfig"; sourceTree = ""; }; 7CEFFAE9AF9284B13C0A758D /* Pods-MastodonTests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - debug.xcconfig"; sourceTree = ""; }; 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; + 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; + 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = ""; }; 8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = ""; }; @@ -2520,6 +2524,8 @@ isa = PBXGroup; children = ( DBF3B7402733EB9400E21627 /* MastodonLocalCode.swift */, + 85904C01293BC0EB0011C817 /* ImageProvider.swift */, + 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */, ); path = Helper; sourceTree = ""; @@ -3172,6 +3178,7 @@ 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */, DB72602725E36A6F00235243 /* MastodonServerRulesViewModel.swift in Sources */, 2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */, + 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */, DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */, DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */, DBEFCD80282A2AA900C0ABEA /* ReportServerRulesViewModel.swift in Sources */, @@ -3308,6 +3315,7 @@ DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */, DB852D1926FAEB6B00FC9D81 /* SidebarViewController.swift in Sources */, 2D206B9225F60EA700143C56 /* UIControl.swift in Sources */, + 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */, DBDFF1932805554900557A48 /* DiscoveryPostsViewModel.swift in Sources */, DB3E6FE72806A7A200B035AE /* DiscoveryItem.swift in Sources */, DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */, diff --git a/Mastodon/Helper/ImageProvider.swift b/Mastodon/Helper/ImageProvider.swift new file mode 100644 index 000000000..11ea6d46e --- /dev/null +++ b/Mastodon/Helper/ImageProvider.swift @@ -0,0 +1,39 @@ +// +// ImageProvider.swift +// Mastodon +// +// Created by Jed Fox on 2022-12-03. +// + +import Foundation +import AlamofireImage +import UniformTypeIdentifiers +import UIKit + +class ImageProvider: NSObject, NSItemProviderWriting { + let url: URL + let filter: ImageFilter? + + init(url: URL, filter: ImageFilter? = nil) { + self.url = url + self.filter = filter + } + + var itemProvider: NSItemProvider { + NSItemProvider(object: self) + } + + static var writableTypeIdentifiersForItemProvider: [String] { + [UTType.png.identifier] + } + + func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, Error?) -> Void) -> Progress? { + let receipt = UIImageView.af.sharedImageDownloader.download(URLRequest(url: url), filter: filter, completion: { response in + switch response.result { + case .failure(let error): completionHandler(nil, error) + case .success(let image): completionHandler(image.pngData(), nil) + } + }) + return receipt?.request.downloadProgress + } +} diff --git a/Mastodon/Helper/URLActivityItemWithMetadata.swift b/Mastodon/Helper/URLActivityItemWithMetadata.swift new file mode 100644 index 000000000..82d1747fe --- /dev/null +++ b/Mastodon/Helper/URLActivityItemWithMetadata.swift @@ -0,0 +1,33 @@ +// +// URLActivityItemWithMetadata.swift +// Mastodon +// +// Created by Jed Fox on 2022-12-03. +// + +import UIKit +import LinkPresentation + +class URLActivityItemWithMetadata: NSObject, UIActivityItemSource { + init(url: URL, configureMetadata: (LPLinkMetadata) -> Void) { + self.url = url + self.metadata = LPLinkMetadata() + metadata.url = url + configureMetadata(metadata) + } + + let url: URL + let metadata: LPLinkMetadata + + func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { + url + } + + func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { + url + } + + func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? { + metadata + } +} diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index ac9da6e81..9865029a1 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -59,8 +59,18 @@ extension DataSourceFacade { status: ManagedObjectRecord ) async throws -> UIActivityViewController { var activityItems: [Any] = try await dependency.context.managedObjectContext.perform { - guard let status = status.object(in: dependency.context.managedObjectContext) else { return [] } - return [StatusActivityItem(status: status)].compactMap { $0 } as [Any] + guard let status = status.object(in: dependency.context.managedObjectContext), + let url = URL(string: status.url ?? status.uri) + else { return [] } + return [ + URLActivityItemWithMetadata(url: url) { metadata in + metadata.title = "\(status.author.displayName) (@\(status.author.acctWithDomain))" + metadata.iconProvider = ImageProvider( + url: status.author.avatarImageURLWithFallback(domain: status.author.domain), + filter: ScaledToSizeFilter(size: CGSize.authorAvatarButtonSize) + ).itemProvider + } + ] as [Any] } var applicationActivities: [UIActivity] = [ SafariActivity(sceneCoordinator: dependency.coordinator), // open URL @@ -77,54 +87,6 @@ extension DataSourceFacade { ) return activityViewController } - - private class StatusActivityItem: NSObject, UIActivityItemSource { - init?(status: Status) { - guard let url = URL(string: status.url ?? status.uri) else { return nil } - self.url = url - self.metadata = LPLinkMetadata() - metadata.url = url - metadata.title = "\(status.author.displayName) (@\(status.author.acctWithDomain))" - metadata.iconProvider = NSItemProvider(object: IconProvider(url: status.author.avatarImageURLWithFallback(domain: status.author.domain))) - } - - let url: URL - let metadata: LPLinkMetadata - - func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { - url - } - - func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { - url - } - - func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? { - metadata - } - - private class IconProvider: NSObject, NSItemProviderWriting { - let url: URL - init(url: URL) { - self.url = url - } - - static var writableTypeIdentifiersForItemProvider: [String] { - [UTType.png.identifier] - } - - func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, Error?) -> Void) -> Progress? { - let filter = ScaledToSizeFilter(size: CGSize.authorAvatarButtonSize) - let receipt = UIImageView.af.sharedImageDownloader.download(URLRequest(url: url), filter: filter, completion: { response in - switch response.result { - case .failure(let error): completionHandler(nil, error) - case .success(let image): completionHandler(image.pngData(), nil) - } - }) - return receipt?.request.downloadProgress - } - } - } } // ActionToolBar diff --git a/ShareActionExtension/Scene/ShareViewController.swift b/ShareActionExtension/Scene/ShareViewController.swift index 4a093becd..cf4d997c1 100644 --- a/ShareActionExtension/Scene/ShareViewController.swift +++ b/ShareActionExtension/Scene/ShareViewController.swift @@ -95,7 +95,8 @@ extension ShareViewController { let composeContentViewModel = ComposeContentViewModel( context: context, authContext: authContext, - kind: .post + destination: .topLevel, + initialContent: "" ) let composeContentViewController = ComposeContentViewController() composeContentViewController.viewModel = composeContentViewModel From 3661b5ce90c0e210acd2ab201d693b6ac7eed19d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 13:25:07 -0500 Subject: [PATCH 382/733] Refactor compose intialization - split ComposeContentViewModel.Kind into Destination (top level/reply) and an initial content string - replies get the mentions prepended to the initial content string --- .../Provider/DataSourceFacade+Status.swift | 2 +- ...tatusTableViewControllerNavigateable.swift | 2 +- .../Scene/Compose/ComposeViewController.swift | 3 +- Mastodon/Scene/Compose/ComposeViewModel.swift | 15 +++-- .../HashtagTimelineViewController.swift | 5 +- .../Scene/Profile/ProfileViewController.swift | 5 +- .../Root/MainTab/MainTabBarController.swift | 4 +- .../Root/Sidebar/SidebarViewController.swift | 2 +- .../Scene/Thread/ThreadViewController.swift | 2 +- Mastodon/Supporting Files/SceneDelegate.swift | 2 +- .../ComposeContentViewModel+DataSource.swift | 11 +--- .../ComposeContentViewModel.swift | 60 +++++++------------ 12 files changed, 49 insertions(+), 64 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index 9865029a1..34cd4121e 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -117,7 +117,7 @@ extension DataSourceFacade { let composeViewModel = ComposeViewModel( context: provider.context, authContext: provider.authContext, - kind: .reply(status: status) + destination: .reply(parent: status) ) _ = provider.coordinator.present( scene: .compose(viewModel: composeViewModel), diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift index e7b55f91c..0e0a24c9b 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift @@ -100,7 +100,7 @@ extension StatusTableViewControllerNavigateableCore where Self: DataSourceProvid let composeViewModel = ComposeViewModel( context: self.context, authContext: authContext, - kind: .reply(status: status) + destination: .reply(parent: status) ) _ = self.coordinator.present( scene: .compose(viewModel: composeViewModel), diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift index fbdbc7d12..9f287dbf8 100644 --- a/Mastodon/Scene/Compose/ComposeViewController.swift +++ b/Mastodon/Scene/Compose/ComposeViewController.swift @@ -34,7 +34,8 @@ final class ComposeViewController: UIViewController, NeedsDependency { return ComposeContentViewModel( context: context, authContext: viewModel.authContext, - kind: viewModel.kind + destination: viewModel.destination, + initialContent: viewModel.initialContent ) }() private(set) lazy var composeContentViewController: ComposeContentViewController = { diff --git a/Mastodon/Scene/Compose/ComposeViewModel.swift b/Mastodon/Scene/Compose/ComposeViewModel.swift index bf234b095..0dcdd9a2d 100644 --- a/Mastodon/Scene/Compose/ComposeViewModel.swift +++ b/Mastodon/Scene/Compose/ComposeViewModel.swift @@ -29,7 +29,8 @@ final class ComposeViewModel { // input let context: AppContext let authContext: AuthContext - let kind: ComposeContentViewModel.Kind + let destination: ComposeContentViewModel.Destination + let initialContent: String let traitCollectionDidChangePublisher = CurrentValueSubject(Void()) // use CurrentValueSubject to make initial event emit @@ -41,17 +42,19 @@ final class ComposeViewModel { init( context: AppContext, authContext: AuthContext, - kind: ComposeContentViewModel.Kind + destination: ComposeContentViewModel.Destination, + initialContent: String = "" ) { self.context = context self.authContext = authContext - self.kind = kind + self.destination = destination + self.initialContent = initialContent // end init self.title = { - switch kind { - case .post, .hashtag, .mention: return L10n.Scene.Compose.Title.newPost - case .reply: return L10n.Scene.Compose.Title.newReply + switch destination { + case .topLevel: return L10n.Scene.Compose.Title.newPost + case .reply: return L10n.Scene.Compose.Title.newReply } }() } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 4a0be3816..1867d2c64 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -162,10 +162,13 @@ extension HashtagTimelineViewController { @objc private func composeBarButtonItemPressed(_ sender: UIBarButtonItem) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + let hashtag = "#" + viewModel.hashtag + UITextChecker.learnWord(hashtag) let composeViewModel = ComposeViewModel( context: context, authContext: viewModel.authContext, - kind: .hashtag(hashtag: viewModel.hashtag) + destination: .topLevel, + initialContent: hashtag ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 1184fb3d7..3dbc03fe4 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -538,10 +538,13 @@ extension ProfileViewController { @objc private func replyBarButtonItemPressed(_ sender: UIBarButtonItem) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) guard let mastodonUser = viewModel.user else { return } + let mention = "@" + mastodonUser.acct + UITextChecker.learnWord(mention) let composeViewModel = ComposeViewModel( context: context, authContext: viewModel.authContext, - kind: .mention(user: mastodonUser.asRecord) + destination: .topLevel, + initialContent: mention ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 2e5d5ae58..1b23b490f 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -379,7 +379,7 @@ extension MainTabBarController { let composeViewModel = ComposeViewModel( context: context, authContext: authContext, - kind: .post + destination: .topLevel ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) } @@ -804,7 +804,7 @@ extension MainTabBarController { let composeViewModel = ComposeViewModel( context: context, authContext: authContext, - kind: .post + destination: .topLevel ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) } diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift index 7c76585a6..0ffcd4c8b 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift @@ -227,7 +227,7 @@ extension SidebarViewController: UICollectionViewDelegate { let composeViewModel = ComposeViewModel( context: context, authContext: authContext, - kind: .post + destination: .topLevel ) _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) default: diff --git a/Mastodon/Scene/Thread/ThreadViewController.swift b/Mastodon/Scene/Thread/ThreadViewController.swift index e8e6ce130..1b386aa6a 100644 --- a/Mastodon/Scene/Thread/ThreadViewController.swift +++ b/Mastodon/Scene/Thread/ThreadViewController.swift @@ -117,7 +117,7 @@ extension ThreadViewController { let composeViewModel = ComposeViewModel( context: context, authContext: viewModel.authContext, - kind: .reply(status: threadContext.status) + destination: .reply(parent: threadContext.status) ) _ = coordinator.present( scene: .compose(viewModel: composeViewModel), diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 4476477fd..336a83f7f 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -185,7 +185,7 @@ extension SceneDelegate { let composeViewModel = ComposeViewModel( context: AppContext.shared, authContext: authContext, - kind: .post + destination: .topLevel ) _ = coordinator?.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): present compose scene") diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift index abbfe0e61..58ceeaa92 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift @@ -47,10 +47,7 @@ extension ComposeContentViewModel { } .store(in: &disposeBag) - switch kind { - case .post: - break - case .reply(let status): + if case .reply(let status) = destination { let cell = composeReplyToTableViewCell // bind frame publisher cell.$framePublisher @@ -66,10 +63,6 @@ extension ComposeContentViewModel { guard let replyTo = status.object(in: context.managedObjectContext) else { return } cell.statusView.configure(status: replyTo) } - case .hashtag: - break - case .mention: - break } } } @@ -83,7 +76,7 @@ extension ComposeContentViewModel: UITableViewDataSource { public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch Section.allCases[section] { case .replyTo: - switch kind { + switch destination { case .reply: return 1 default: return 0 } diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index a1ddb6101..066a7ff78 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -32,7 +32,7 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { // input let context: AppContext - let kind: Kind + let destination: Destination weak var delegate: ComposeContentViewModelDelegate? @Published var viewLayoutFrame = ViewLayoutFrame() @@ -59,8 +59,7 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { customEmojiPickerInputViewModel.configure(textInput: textView) } } - // for hashtag: "# " - // for mention: "@ " + // allow dismissing the compose view without confirmation if content == intialContent @Published public var initialContent = "" @Published public var content = "" @Published public var contentWeightedLength = 0 @@ -138,11 +137,12 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { public init( context: AppContext, authContext: AuthContext, - kind: Kind + destination: Destination, + initialContent: String ) { self.context = context self.authContext = authContext - self.kind = kind + self.destination = destination self.visibility = { // default private when user locked var visibility: Mastodon.Entity.Status.Visibility = { @@ -152,8 +152,7 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { return author.locked ? .private : .public }() // set visibility for reply post - switch kind { - case .reply(let record): + if case .reply(let record) = destination { context.managedObjectContext.performAndWait { guard let status = record.object(in: context.managedObjectContext) else { assertionFailure() @@ -173,8 +172,6 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { break } } - default: - break } return visibility }() @@ -185,7 +182,8 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { // end init // setup initial value - switch kind { + let initialContentWithSpace = initialContent.isEmpty ? "" : initialContent + " " + switch destination { case .reply(let record): context.managedObjectContext.performAndWait { guard let status = record.object(in: context.managedObjectContext) else { @@ -214,29 +212,15 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { } let initialComposeContent = mentionAccts.joined(separator: " ") - let preInsertedContent: String? = initialComposeContent.isEmpty ? nil : initialComposeContent + " " - self.initialContent = preInsertedContent ?? "" - self.content = preInsertedContent ?? "" + let preInsertedContent = initialComposeContent.isEmpty ? "" : initialComposeContent + " " + self.initialContent = preInsertedContent + initialContentWithSpace + self.content = preInsertedContent + initialContentWithSpace } - case .hashtag(let hashtag): - let initialComposeContent = "#" + hashtag - UITextChecker.learnWord(initialComposeContent) - let preInsertedContent = initialComposeContent + " " - self.initialContent = preInsertedContent - self.content = preInsertedContent - case .mention(let record): - context.managedObjectContext.performAndWait { - guard let user = record.object(in: context.managedObjectContext) else { return } - let initialComposeContent = "@" + user.acct - UITextChecker.learnWord(initialComposeContent) - let preInsertedContent = initialComposeContent + " " - self.initialContent = preInsertedContent - self.content = preInsertedContent - } - case .post: - break + case .topLevel: + self.initialContent = initialContentWithSpace + self.content = initialContentWithSpace } - + // set limit let _configuration: Mastodon.Entity.Instance.Configuration? = { var configuration: Mastodon.Entity.Instance.Configuration? = nil @@ -443,11 +427,9 @@ extension ComposeContentViewModel { } extension ComposeContentViewModel { - public enum Kind { - case post - case hashtag(hashtag: String) - case mention(user: ManagedObjectRecord) - case reply(status: ManagedObjectRecord) + public enum Destination { + case topLevel + case reply(parent: ManagedObjectRecord) } public enum ScrollViewState { @@ -530,10 +512,10 @@ extension ComposeContentViewModel { return MastodonStatusPublisher( author: author, replyTo: { - switch self.kind { - case .reply(let status): return status - default: return nil + if case .reply(let status) = destination { + return status } + return nil }(), isContentWarningComposing: isContentWarningActive, contentWarning: contentWarning, From 17b39da316abe386de0ed32a98427430cb2cd422 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 13:38:32 -0500 Subject: [PATCH 383/733] =?UTF-8?q?Add=20=E2=80=9CCopy,=E2=80=9D=20?= =?UTF-8?q?=E2=80=9CShare,=E2=80=9D=20and=20=E2=80=9CShare=20Link=20in=20P?= =?UTF-8?q?ost=E2=80=9D=20actions=20to=20cards?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input/Base.lproj/app.json | 3 + Localization/app.json | 3 + ...Provider+StatusTableViewCellDelegate.swift | 96 +++++++++++++++++++ .../StatusTableViewCellDelegate.swift | 10 ++ .../Generated/Strings.swift | 8 ++ .../Resources/Base.lproj/Localizable.strings | 3 + .../View/Content/NotificationView.swift | 9 ++ .../View/Content/StatusCardControl.swift | 25 ++++- .../View/Content/StatusView+ViewModel.swift | 6 -- .../MastodonUI/View/Content/StatusView.swift | 14 +++ 10 files changed, 169 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index e09ab983c..4788a99d4 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -78,6 +78,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -133,6 +134,7 @@ "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -154,6 +156,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { diff --git a/Localization/app.json b/Localization/app.json index e09ab983c..4788a99d4 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -78,6 +78,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -133,6 +134,7 @@ "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -154,6 +156,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index 721263f30..0521a3486 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -10,6 +10,9 @@ import CoreDataStack import MetaTextKit import MastodonCore import MastodonUI +import MastodonLocalization +import MastodonAsset +import LinkPresentation // MARK: - header extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { @@ -150,6 +153,99 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte } } + func tableViewCell( + _ cell: UITableViewCell, + statusView: StatusView, + cardControl: StatusCardControl, + didTapURL url: URL + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + + await DataSourceFacade.responseToURLAction( + provider: self, + status: status, + url: url + ) + } + } + + func tableViewCell( + _ cell: UITableViewCell, + statusView: StatusView, + cardControlMenu statusCardControl: StatusCardControl + ) -> UIMenu? { + guard let card = statusView.viewModel.card, + let url = card.url else { + return nil + } + + return UIMenu(children: [ + UIAction( + title: L10n.Common.Controls.Actions.copy, + image: UIImage(systemName: "doc.on.doc") + ) { _ in + UIPasteboard.general.url = url + }, + UIAction( + title: L10n.Common.Controls.Actions.share, + image: Asset.Arrow.squareAndArrowUp.image.withRenderingMode(.alwaysTemplate) + ) { _ in + Task { + await MainActor.run { + let activityViewController = UIActivityViewController( + activityItems: [ + URLActivityItemWithMetadata(url: url) { metadata in + metadata.title = card.title + + if let image = card.imageURL { + metadata.iconProvider = ImageProvider(url: image, filter: nil).itemProvider + } + } + ], + applicationActivities: [] + ) + self.coordinator.present( + scene: .activityViewController( + activityViewController: activityViewController, + sourceView: statusCardControl, barButtonItem: nil + ), + from: self, + transition: .activityViewControllerPresent(animated: true) + ) + } + } + }, + UIAction( + title: L10n.Common.Controls.Status.Actions.shareLinkInPost, + image: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) + ) { _ in + Task { + await MainActor.run { + self.coordinator.present( + scene: .compose(viewModel: ComposeViewModel( + context: self.context, + authContext: self.authContext, + destination: .topLevel, + initialContent: L10n.Common.Controls.Status.linkViaUser(url.absoluteString, "@" + (statusView.viewModel.authorUsername ?? "")) + )), + from: self, + transition: .modal(animated: true) + ) + } + } + } + ]) + } + } // MARK: - media diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift index e76ba5006..f21e0573c 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift @@ -37,6 +37,8 @@ protocol StatusTableViewCellDelegate: AnyObject, AutoGenerateProtocolDelegate { func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, cardControl: StatusCardControl, didTapURL url: URL) + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, cardControlMenu: StatusCardControl) -> UIMenu? func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, accessibilityActivate: Void) // sourcery:end } @@ -102,6 +104,14 @@ extension StatusViewDelegate where Self: StatusViewContainerTableViewCell { delegate?.tableViewCell(self, statusView: statusView, statusMetricView: statusMetricView, favoriteButtonDidPressed: button) } + func statusView(_ statusView: StatusView, cardControl: StatusCardControl, didTapURL url: URL) { + delegate?.tableViewCell(self, statusView: statusView, cardControl: cardControl, didTapURL: url) + } + + func statusView(_ statusView: StatusView, cardControlMenu: StatusCardControl) -> UIMenu? { + return delegate?.tableViewCell(self, statusView: statusView, cardControlMenu: cardControlMenu) + } + func statusView(_ statusView: StatusView, accessibilityActivate: Void) { delegate?.tableViewCell(self, statusView: statusView, accessibilityActivate: accessibilityActivate) } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 335638030..a2d2faf73 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -112,6 +112,8 @@ public enum L10n { public static let confirm = L10n.tr("Localizable", "Common.Controls.Actions.Confirm", fallback: "Confirm") /// Continue public static let `continue` = L10n.tr("Localizable", "Common.Controls.Actions.Continue", fallback: "Continue") + /// Copy + public static let copy = L10n.tr("Localizable", "Common.Controls.Actions.Copy", fallback: "Copy") /// Copy Photo public static let copyPhoto = L10n.tr("Localizable", "Common.Controls.Actions.CopyPhoto", fallback: "Copy Photo") /// Delete @@ -272,6 +274,10 @@ public enum L10n { public enum Status { /// Content Warning public static let contentWarning = L10n.tr("Localizable", "Common.Controls.Status.ContentWarning", fallback: "Content Warning") + /// %@ via %@ + public static func linkViaUser(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Status.LinkViaUser", String(describing: p1), String(describing: p2), fallback: "%@ via %@") + } /// Load Embed public static let loadEmbed = L10n.tr("Localizable", "Common.Controls.Status.LoadEmbed", fallback: "Load Embed") /// Tap anywhere to reveal @@ -303,6 +309,8 @@ public enum L10n { public static let reblog = L10n.tr("Localizable", "Common.Controls.Status.Actions.Reblog", fallback: "Reblog") /// Reply public static let reply = L10n.tr("Localizable", "Common.Controls.Status.Actions.Reply", fallback: "Reply") + /// Share Link in Post + public static let shareLinkInPost = L10n.tr("Localizable", "Common.Controls.Status.Actions.ShareLinkInPost", fallback: "Share Link in Post") /// Show GIF public static let showGif = L10n.tr("Localizable", "Common.Controls.Status.Actions.ShowGif", fallback: "Show GIF") /// Show image diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 3c3e16ca3..88a67ac1d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -31,6 +31,7 @@ Please check your internet connection."; "Common.Controls.Actions.Compose" = "Compose"; "Common.Controls.Actions.Confirm" = "Confirm"; "Common.Controls.Actions.Continue" = "Continue"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Copy Photo"; "Common.Controls.Actions.Delete" = "Delete"; "Common.Controls.Actions.Discard" = "Discard"; @@ -100,6 +101,7 @@ Please check your internet connection."; "Common.Controls.Status.Actions.Menu" = "Menu"; "Common.Controls.Status.Actions.Reblog" = "Reblog"; "Common.Controls.Status.Actions.Reply" = "Reply"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Show GIF"; "Common.Controls.Status.Actions.ShowImage" = "Show image"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; @@ -107,6 +109,7 @@ Please check your internet connection."; "Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; "Common.Controls.Status.Actions.Unreblog" = "Undo reblog"; "Common.Controls.Status.ContentWarning" = "Content Warning"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index eb077d6db..c44a06b7d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -611,6 +611,15 @@ extension NotificationView: StatusViewDelegate { assertionFailure() } + public func statusView(_ statusView: StatusView, cardControl: StatusCardControl, didTapURL url: URL) { + assertionFailure() + } + + public func statusView(_ statusView: StatusView, cardControlMenu: StatusCardControl) -> UIMenu? { + assertionFailure() + return nil + } + } // MARK: - MastodonMenuDelegate diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 51c125a87..433719a06 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -14,8 +14,13 @@ import CoreDataStack import UIKit import WebKit +public protocol StatusCardControlDelegate: AnyObject { + func statusCardControl(_ statusCardControl: StatusCardControl, didTapURL url: URL) + func statusCardControlMenu(_ statusCardControl: StatusCardControl) -> UIMenu? +} + public final class StatusCardControl: UIControl { - public var urlToOpen = PassthroughSubject() + public weak var delegate: StatusCardControlDelegate? private var disposeBag = Set() @@ -130,6 +135,8 @@ public final class StatusCardControl: UIControl { showEmbedButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor), showEmbedButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor), ]) + + addInteraction(UIContextMenuInteraction(delegate: self)) } required init?(coder: NSCoder) { @@ -238,6 +245,7 @@ public final class StatusCardControl: UIControl { } } +// MARK: WKWebView delegates extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { fileprivate func showWebView() { let webView = setupWebView() @@ -279,7 +287,7 @@ extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .other, let url = navigationAction.request.url, url.absoluteString != "about:blank" { - urlToOpen.send(url) + delegate?.statusCardControl(self, didTapURL: url) return .cancel } return .allow @@ -291,6 +299,19 @@ extension StatusCardControl: WKNavigationDelegate, WKUIDelegate { } } +// MARK: UIContextMenuInteractionDelegate +extension StatusCardControl { + public override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { + return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { elements in + self.delegate?.statusCardControlMenu(self) + } + } + + public override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForDismissingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { + UITargetedPreview(view: self) + } +} + private extension StatusCardControl { enum Layout: Equatable { case compact diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 634473a65..77de106b1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -494,12 +494,6 @@ extension StatusView.ViewModel { statusView.setStatusCardControlDisplay() } .store(in: &disposeBag) - - statusView.statusCardControl.urlToOpen - .sink { url in - statusView.delegate?.statusView(statusView, didTapCardWithURL: url) - } - .store(in: &disposeBag) } private func bindToolbar(statusView: StatusView) { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 249e2e1ec..539276f41 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -33,6 +33,8 @@ public protocol StatusViewDelegate: AnyObject { func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton) func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) + func statusView(_ statusView: StatusView, cardControl: StatusCardControl, didTapURL url: URL) + func statusView(_ statusView: StatusView, cardControlMenu: StatusCardControl) -> UIMenu? // a11y func statusView(_ statusView: StatusView, accessibilityActivate: Void) @@ -264,6 +266,7 @@ extension StatusView { // card statusCardControl.addTarget(self, action: #selector(statusCardControlPressed), for: .touchUpInside) + statusCardControl.delegate = self // media mediaGridContainerView.delegate = self @@ -667,6 +670,17 @@ extension StatusView: MastodonMenuDelegate { } } +// MARK: StatusCardControlDelegate +extension StatusView: StatusCardControlDelegate { + public func statusCardControl(_ statusCardControl: StatusCardControl, didTapURL url: URL) { + delegate?.statusView(self, cardControl: statusCardControl, didTapURL: url) + } + + public func statusCardControlMenu(_ statusCardControl: StatusCardControl) -> UIMenu? { + delegate?.statusView(self, cardControlMenu: statusCardControl) + } +} + #if DEBUG import SwiftUI From 1379cdc448370c4ab05b360be3c7cbdb08fa287e Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 13:41:51 -0500 Subject: [PATCH 384/733] Disable cards in notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit both to save space and because I’m too lazy to wire up the delegate methods for the menu --- ...er+NotificationTableViewCellDelegate.swift | 55 ------------------- .../NotificationTableViewCellDelegate.swift | 10 ---- .../View/Content/NotificationView.swift | 11 +--- .../MastodonUI/View/Content/StatusView.swift | 2 + 4 files changed, 3 insertions(+), 75 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift index 279cb562e..e868f418f 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift @@ -516,61 +516,6 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider & Aut } -// MARK: - card -extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { - - func tableViewCell( - _ cell: UITableViewCell, - notificationView: NotificationView, - statusView: StatusView, - didTapCardWithURL url: URL - ) { - Task { - let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) - guard let item = await item(from: source) else { - assertionFailure() - return - } - guard case let .status(status) = item else { - assertionFailure("only works for status data provider") - return - } - - await DataSourceFacade.responseToURLAction( - provider: self, - status: status, - url: url - ) - } - } - - func tableViewCell( - _ cell: UITableViewCell, - notificationView: NotificationView, - quoteStatusView: StatusView, - didTapCardWithURL url: URL - ) { - Task { - let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) - guard let item = await item(from: source) else { - assertionFailure() - return - } - guard case let .status(status) = item else { - assertionFailure("only works for status data provider") - return - } - - await DataSourceFacade.responseToURLAction( - provider: self, - status: status, - url: url - ) - } - } - -} - // MARK: a11y extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider { func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void) { diff --git a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift index 45ad59334..7a603d5f0 100644 --- a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift +++ b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift @@ -28,13 +28,11 @@ protocol NotificationTableViewCellDelegate: AnyObject, AutoGenerateProtocolDeleg func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, acceptFollowRequestButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) - func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) - func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void) @@ -65,10 +63,6 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, metaText: metaText, didSelectMeta: meta) } - func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) { - delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, didTapCardWithURL: url) - } - func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) { delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, spoilerOverlayViewDidPressed: overlayView) } @@ -89,10 +83,6 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, metaText: metaText, didSelectMeta: meta) } - func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) { - delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, didTapCardWithURL: url) - } - func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) { delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, spoilerOverlayViewDidPressed: overlayView) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index c44a06b7d..9196c340e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -22,7 +22,6 @@ public protocol NotificationViewDelegate: AnyObject { func notificationView(_ notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton) func notificationView(_ notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) - func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func notificationView(_ notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) @@ -30,7 +29,6 @@ public protocol NotificationViewDelegate: AnyObject { func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) - func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) @@ -499,14 +497,7 @@ extension NotificationView { // MARK: - StatusViewDelegate extension NotificationView: StatusViewDelegate { public func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) { - switch statusView { - case self.statusView: - delegate?.notificationView(self, statusView: statusView, didTapCardWithURL: url) - case quoteStatusView: - delegate?.notificationView(self, quoteStatusView: statusView, didTapCardWithURL: url) - default: - assertionFailure() - } + assertionFailure() } public func statusView(_ statusView: StatusView, headerDidPressed header: UIView) { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 539276f41..2b9e84e5e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -488,6 +488,7 @@ extension StatusView.Style { statusView.headerAdaptiveMarginContainerView.removeFromSuperview() statusView.authorAdaptiveMarginContainerView.removeFromSuperview() + statusView.statusCardControl.removeFromSuperview() } func notificationQuote(statusView: StatusView) { @@ -496,6 +497,7 @@ extension StatusView.Style { statusView.contentAdaptiveMarginContainerView.bottomLayoutConstraint?.constant = 16 // fix bottom margin missing issue statusView.pollAdaptiveMarginContainerView.bottomLayoutConstraint?.constant = 16 // fix bottom margin missing issue statusView.actionToolbarAdaptiveMarginContainerView.removeFromSuperview() + statusView.statusCardControl.removeFromSuperview() } func composeStatusReplica(statusView: StatusView) { From 3c806393a385506d584c95c8bf1649341ef72521 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 14:00:01 -0500 Subject: [PATCH 385/733] Fix core data update --- .../CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index 2145ac780..e660b0a08 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 5.xcdatamodel + CoreData 6.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents index c9c274ddc..b146c2b97 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents @@ -224,6 +224,7 @@ + @@ -269,6 +270,7 @@ + From 285fbd4247815b9a79f380a510f681edfb6aeec3 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 14:02:22 -0500 Subject: [PATCH 386/733] Fix divider not visible in compact cards --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 433719a06..3f297424c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -221,6 +221,7 @@ public final class StatusCardControl: UIControl { imageView.widthAnchor.constraint(equalToConstant: 85), heightAnchor.constraint(equalToConstant: 85).priority(.defaultLow - 1), heightAnchor.constraint(greaterThanOrEqualToConstant: 85), + dividerView.heightAnchor.constraint(equalTo: containerStackView.heightAnchor), ] dividerConstraint = dividerView.widthAnchor.constraint(equalToConstant: pixelSize).activate() } From 1642839084f8f7cfd04d92ccdea486e35028355e Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 14:03:53 -0500 Subject: [PATCH 387/733] Force card into large mode if it has an embed --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 3f297424c..6b6296cef 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -326,7 +326,7 @@ private extension Card { if !aspectRatio.isFinite { aspectRatio = 1 } - return abs(aspectRatio - 1) < 0.05 || image == nil + return (abs(aspectRatio - 1) < 0.05 || image == nil) && html == nil ? .compact : .large(aspectRatio: aspectRatio) } From 4f8ca8d481a42fd170c9859a1f23e9f42346239d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 14:07:43 -0500 Subject: [PATCH 388/733] Use a non-opaque background color for the image view --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 6b6296cef..aaca1cd6c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -242,7 +242,7 @@ public final class StatusCardControl: UIControl { private func apply(theme: Theme) { layer.borderColor = theme.separator.cgColor dividerView.backgroundColor = theme.separator - imageView.backgroundColor = theme.systemElevatedBackgroundColor + imageView.backgroundColor = UIColor.tertiarySystemFill } } From 41e9cfa80d0f1e8c3712d2002d9efbf52046e745 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 3 Dec 2022 14:18:39 -0500 Subject: [PATCH 389/733] Fix i18n formatting for a11y.plural.count.characters_left --- Localization/Localizable.stringsdict | 12 ++++++------ .../input/Base.lproj/Localizable.stringsdict | 12 ++++++------ .../MastodonLocalization/Generated/Strings.swift | 4 ++-- .../Resources/Base.lproj/Localizable.stringsdict | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Localization/Localizable.stringsdict b/Localization/Localizable.stringsdict index f8964ca5d..37ce1f032 100644 --- a/Localization/Localizable.stringsdict +++ b/Localization/Localizable.stringsdict @@ -71,7 +71,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -79,15 +79,15 @@ NSStringFormatValueTypeKey ld zero - no characters + no characters left one - 1 character + 1 character left few - %ld characters + %ld characters left many - %ld characters + %ld characters left other - %ld characters + %ld characters left plural.count.followed_by_and_mutual diff --git a/Localization/StringsConvertor/input/Base.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/Base.lproj/Localizable.stringsdict index f8964ca5d..37ce1f032 100644 --- a/Localization/StringsConvertor/input/Base.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/Base.lproj/Localizable.stringsdict @@ -71,7 +71,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -79,15 +79,15 @@ NSStringFormatValueTypeKey ld zero - no characters + no characters left one - 1 character + 1 character left few - %ld characters + %ld characters left many - %ld characters + %ld characters left other - %ld characters + %ld characters left plural.count.followed_by_and_mutual diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index bafed05f6..aff1bdf00 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1338,9 +1338,9 @@ public enum L10n { public enum A11y { public enum Plural { public enum Count { - /// Plural format key: "%#@character_count@ left" + /// Plural format key: "%#@character_count@" public static func charactersLeft(_ p1: Int) -> String { - return L10n.tr("Localizable", "a11y.plural.count.characters_left", p1, fallback: "Plural format key: \"%#@character_count@ left\"") + return L10n.tr("Localizable", "a11y.plural.count.characters_left", p1, fallback: "Plural format key: \"%#@character_count@\"") } /// Plural format key: "Input limit exceeds %#@character_count@" public static func inputLimitExceeds(_ p1: Int) -> String { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.stringsdict index f8964ca5d..37ce1f032 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.stringsdict @@ -71,7 +71,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -79,15 +79,15 @@ NSStringFormatValueTypeKey ld zero - no characters + no characters left one - 1 character + 1 character left few - %ld characters + %ld characters left many - %ld characters + %ld characters left other - %ld characters + %ld characters left plural.count.followed_by_and_mutual From d57ae66b808b6a0533bec95b85a1d4f788878352 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 3 Dec 2022 21:12:34 +0100 Subject: [PATCH 390/733] New translations app.json (Thai) --- .../StringsConvertor/input/th.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 7fdd0e66c..ffd502057 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "หน้าแรก", - "search_and_explore": "Search and Explore", + "search_and_explore": "ค้นหาและสำรวจ", "notifications": "การแจ้งเตือน", "profile": "โปรไฟล์" }, @@ -724,15 +724,15 @@ "title": "ที่คั่นหน้า" }, "followed_tags": { - "title": "Followed Tags", + "title": "แท็กที่ติดตาม", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "โพสต์", + "participants": "ผู้เข้าร่วม", + "posts_today": "โพสต์วันนี้" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "ติดตาม", + "unfollow": "เลิกติดตาม" } } } From ef07d9c9638cf2fc92c6b04bc993a13bc486e808 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Dec 2022 20:13:17 +0100 Subject: [PATCH 391/733] New translations app.json (Turkish) --- .../StringsConvertor/input/tr.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 9be7bbfe5..830238de8 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -95,8 +95,8 @@ }, "tabs": { "home": "Ana Sayfa", - "search_and_explore": "Search and Explore", - "notifications": "Notifications", + "search_and_explore": "Ara ve Keşfet", + "notifications": "Bildirimler", "profile": "Profil" }, "keyboard": { @@ -187,8 +187,8 @@ "unmute_user": "Sesini aç %s", "muted": "Susturuldu", "edit_info": "Bilgiyi Düzenle", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "Yeniden Paylaşımları Göster", + "hide_reblogs": "Yeniden Paylaşımları Gizle" }, "timeline": { "filtered": "Filtrelenmiş", @@ -220,14 +220,14 @@ }, "login": { "title": "Tekrar hoş geldin", - "subtitle": "Log you in on the server you created your account on.", + "subtitle": "Hesabını oluşturduğun sunucuya giriş yap.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Bir URL girin ya da sunucunuzu arayın" } }, "server_picker": { "title": "Mastodon, farklı topluluklardaki kullanıcılardan oluşur.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "Bölgenize dayalı, ilginize dayalı ya da genel amaçlı bir sunucu seçin. Hangi sunucuda olduğunuz fark etmeksizin Mastodon'daki herkes ile konuşabilirsiniz.", "button": { "category": { "all": "Tümü", @@ -254,7 +254,7 @@ "category": "KATEGORİ" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Topluluklar arayın ya da bir URL girin" }, "empty_state": { "finding_servers": "Mevcut sunucular aranıyor...", @@ -391,9 +391,9 @@ "load_failed": "Yükleme Başarısız", "upload_failed": "Upload Failed", "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", + "attachment_too_large": "Ek boyutu çok büyük", "compressing_state": "Sıkıştırılıyor...", - "server_processing_state": "Server Processing..." + "server_processing_state": "Sunucu İşliyor..." }, "poll": { "duration_time": "Süre: %s", @@ -404,7 +404,7 @@ "three_days": "3 Gün", "seven_days": "7 Gün", "option_number": "Seçenek %ld", - "the_poll_is_invalid": "The poll is invalid", + "the_poll_is_invalid": "Anket geçersiz", "the_poll_has_empty_option": "The poll has empty option" }, "content_warning": { From dd6f5f4254df344816ead7338e9dd106d58493f0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Dec 2022 21:18:26 +0100 Subject: [PATCH 392/733] New translations app.json (Turkish) --- .../StringsConvertor/input/tr.lproj/app.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 830238de8..74a138304 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -389,8 +389,8 @@ "description_photo": "Görme engelliler için fotoğrafı tarif edin...", "description_video": "Görme engelliler için videoyu tarif edin...", "load_failed": "Yükleme Başarısız", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", + "upload_failed": "Yükleme Başarısız", + "can_not_recognize_this_media_attachment": "Ekteki medya uzantısı görüntülenemiyor", "attachment_too_large": "Ek boyutu çok büyük", "compressing_state": "Sıkıştırılıyor...", "server_processing_state": "Sunucu İşliyor..." @@ -427,8 +427,8 @@ "enable_content_warning": "İçerik Uyarısını Etkinleştir", "disable_content_warning": "İçerik Uyarısını Kapat", "post_visibility_menu": "Gönderi Görünürlüğü Menüsü", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Gönderi Seçenekleri", + "posting_as": "%s olarak paylaşılıyor" }, "keyboard": { "discard_post": "Gönderiyi İptal Et", @@ -455,8 +455,8 @@ "content": "İçerik" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "%s tarafında onaylı", + "long": "%s adresinin sahipliği kontrol edilmiş" } }, "segmented_control": { @@ -484,12 +484,12 @@ "message": "%s engellemeyi kaldırmayı onaylayın" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Yeniden Paylaşımları Göster", + "message": "Yeniden paylaşımları göstermeyi onayla" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Yeniden Paylaşımları Gizle", + "message": "Yeniden paylaşımları gizlemeyi onayla" } }, "accessibility": { @@ -508,8 +508,8 @@ "footer": "Diğer sunucudaki takip edilenler gösterilemiyor." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Tanıyor olabileceğin takipçiler", + "followed_by_names": "%s tarafından takip ediliyor" }, "favorited_by": { "title": "Favorited By" @@ -698,9 +698,9 @@ "unfollow_user": "Takipten çık %s", "mute_user": "Sustur %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "block_user": "%s kişisini engelle", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Artık sizi takip edemez ve gönderilerinizi göremezler ama engellendiklerini görebilirler.", + "while_we_review_this_you_can_take_action_against_user": "Biz bunu incelerken siz %s hesabına karşı önlem alabilirsiniz" } }, "preview": { @@ -724,15 +724,15 @@ "title": "Yer İmleri" }, "followed_tags": { - "title": "Followed Tags", + "title": "Takip Edilen Etiketler", "header": { - "posts": "posts", - "participants": "participants", + "posts": "gönderiler", + "participants": "katılımcılar", "posts_today": "posts today" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Takip et", + "unfollow": "Takibi bırak" } } } From 52fa05b0fc3bd1e499e6494d7deb44a00c532c4a Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Mon, 5 Dec 2022 10:21:29 -0500 Subject: [PATCH 393/733] Add UIWindow subclass to display all touches. --- .../View/Window/TouchesVisibleWindow.swift | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift new file mode 100644 index 000000000..26971ef1e --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -0,0 +1,134 @@ +// +// File.swift +// +// +// Created by Chase Carroll on 12/5/22. +// + +#if DEBUG + +import UIKit + +fileprivate final class TouchView: UIView { + + fileprivate lazy var blurView: UIVisualEffectView = { + let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight) + return UIVisualEffectView(effect: blurEffect) + }() + + override var frame: CGRect { + didSet { + layer.cornerRadius = frame.height / 2.0 + } + } + + override init(frame: CGRect) { + super.init(frame: frame) + + backgroundColor = .clear + layer.masksToBounds = true + layer.cornerCurve = .circular + layer.borderColor = UIColor.white.cgColor + layer.borderWidth = 2.0 + + addSubview(blurView) + } + + @available(iOS, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + blurView.frame = bounds + } + +} + + +public final class TouchesVisibleWindow: UIWindow { + + var touchesVisible = false { + didSet { + if !touchesVisible { + cleanUpAllTouches() + } + } + } + + fileprivate var touchViews: [UITouch : TouchView] = [:] + + fileprivate func newTouchView() -> TouchView { + let touchSize = 44.0 + return TouchView(frame: CGRect( + origin: .zero, + size: CGSize( + width: touchSize, + height: touchSize + ) + )) + } + + fileprivate func cleanupTouch(_ touch: UITouch) { + guard let touchView = touchViews[touch] else { + return + } + + touchView.removeFromSuperview() + touchViews.removeValue(forKey: touch) + } + + fileprivate func cleanUpAllTouches() { + for (_, touchView) in touchViews { + touchView.removeFromSuperview() + } + + touchViews.removeAll() + } + + public override func sendEvent(_ event: UIEvent) { + if !touchesVisible { + super.sendEvent(event) + return + } + + let touches = event.allTouches + + guard + let touches = touches, + touches.count > 0 + else { + cleanUpAllTouches() + super.sendEvent(event) + return + } + + for touch in touches { + let touchLocation = touch.location(in: self) + switch touch.phase { + case .began: + let touchView = newTouchView() + touchView.center = touchLocation + addSubview(touchView) + touchViews[touch] = touchView + + case .moved: + guard let touchView = touchViews[touch] else { + return + } + touchView.center = touchLocation + + case .ended, .cancelled: + cleanupTouch(touch) + + default: + break + } + } + + super.sendEvent(event) + } +} + +#endif From 12791ddf284ade317f0901ce7e6dc16f41dcffea Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Mon, 5 Dec 2022 10:22:14 -0500 Subject: [PATCH 394/733] Use UIWindow subclass in DEBUG builds --- Mastodon/Supporting Files/SceneDelegate.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 15c4069cb..e3256d260 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -11,6 +11,7 @@ import Combine import CoreDataStack import MastodonCore import MastodonExtension +import MastodonUI #if PROFILE import FPSIndicator @@ -35,8 +36,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } + #if DEBUG + let window = TouchesVisibleWindow(windowScene: windowScene) + self.window = window + #else let window = UIWindow(windowScene: windowScene) self.window = window + #endif // set tint color window.tintColor = UIColor.label From 7f58422900e6b1a98f9c0d90c1d3cae24acab7af Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Mon, 5 Dec 2022 10:32:10 -0500 Subject: [PATCH 395/733] Add debug menu option Puts an option in the debug menu for toggling on/off visible touches. --- .../HomeTimeline/HomeTimelineViewController+DebugAction.swift | 4 ++++ .../Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift index ff90775ff..6bded8c37 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift @@ -122,6 +122,10 @@ extension HomeTimelineViewController { identifier: nil, options: [], children: [ + UIAction(title: "Toggle Visible Touches", image: UIImage(systemName: "hand.tap"), attributes: []) { [weak self] action in + guard let window = UIApplication.shared.keyWindow as? TouchesVisibleWindow else { return } + window.touchesVisible = !window.touchesVisible + }, UIAction(title: "Toggle EmptyView", image: UIImage(systemName: "clear"), attributes: []) { [weak self] action in guard let self = self else { return } if self.emptyView.superview != nil { diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index 26971ef1e..7a8a37976 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -49,7 +49,7 @@ fileprivate final class TouchView: UIView { public final class TouchesVisibleWindow: UIWindow { - var touchesVisible = false { + public var touchesVisible = false { didSet { if !touchesVisible { cleanUpAllTouches() From 4689c8e78fc9e59c0cf1d6cac516e5d13dba5e0e Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Mon, 5 Dec 2022 16:01:41 -0500 Subject: [PATCH 396/733] Use modern APIs for accessing key window Shouldn't be relying on deprecated API. Tsk. Tsk. --- Mastodon/Extension/UIApplication.swift | 8 ++++++++ .../HomeTimelineViewController+DebugAction.swift | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Mastodon/Extension/UIApplication.swift b/Mastodon/Extension/UIApplication.swift index 38080fdab..74019b0ae 100644 --- a/Mastodon/Extension/UIApplication.swift +++ b/Mastodon/Extension/UIApplication.swift @@ -22,5 +22,13 @@ extension UIApplication { return version == build ? "v\(version)" : "v\(version) (\(build))" } + + func getKeyWindow() -> UIWindow? { + return UIApplication + .shared + .connectedScenes + .flatMap { ($0 as? UIWindowScene)?.windows ?? [] } + .first { $0.isKeyWindow } + } } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift index 6bded8c37..8ad798165 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift @@ -122,8 +122,8 @@ extension HomeTimelineViewController { identifier: nil, options: [], children: [ - UIAction(title: "Toggle Visible Touches", image: UIImage(systemName: "hand.tap"), attributes: []) { [weak self] action in - guard let window = UIApplication.shared.keyWindow as? TouchesVisibleWindow else { return } + UIAction(title: "Toggle Visible Touches", image: UIImage(systemName: "hand.tap"), attributes: []) { _ in + guard let window = UIApplication.shared.getKeyWindow() as? TouchesVisibleWindow else { return } window.touchesVisible = !window.touchesVisible }, UIAction(title: "Toggle EmptyView", image: UIImage(systemName: "clear"), attributes: []) { [weak self] action in From 5648b13517bb3eb3ad04b928583c319892462d99 Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Mon, 5 Dec 2022 20:22:50 -0500 Subject: [PATCH 397/733] Tidy up. --- .../View/Window/TouchesVisibleWindow.swift | 85 +++++++++---------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index 7a8a37976..bdde38ed0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -9,12 +9,10 @@ import UIKit +/// View that represents a single touch from the user. fileprivate final class TouchView: UIView { - fileprivate lazy var blurView: UIVisualEffectView = { - let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight) - return UIVisualEffectView(effect: blurEffect) - }() + private let blurView: UIVisualEffectView override var frame: CGRect { didSet { @@ -23,6 +21,9 @@ fileprivate final class TouchView: UIView { } override init(frame: CGRect) { + let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight) + blurView = UIVisualEffectView(effect: blurEffect) + super.init(frame: frame) backgroundColor = .clear @@ -47,6 +48,7 @@ fileprivate final class TouchView: UIView { } +/// `UIWindow` subclass that renders visual representations of the user's touches. public final class TouchesVisibleWindow: UIWindow { public var touchesVisible = false { @@ -57,9 +59,9 @@ public final class TouchesVisibleWindow: UIWindow { } } - fileprivate var touchViews: [UITouch : TouchView] = [:] + private var touchViews: [UITouch : TouchView] = [:] - fileprivate func newTouchView() -> TouchView { + private func newTouchView() -> TouchView { let touchSize = 44.0 return TouchView(frame: CGRect( origin: .zero, @@ -70,7 +72,7 @@ public final class TouchesVisibleWindow: UIWindow { )) } - fileprivate func cleanupTouch(_ touch: UITouch) { + private func cleanupTouch(_ touch: UITouch) { guard let touchView = touchViews[touch] else { return } @@ -79,7 +81,7 @@ public final class TouchesVisibleWindow: UIWindow { touchViews.removeValue(forKey: touch) } - fileprivate func cleanUpAllTouches() { + private func cleanUpAllTouches() { for (_, touchView) in touchViews { touchView.removeFromSuperview() } @@ -88,42 +90,39 @@ public final class TouchesVisibleWindow: UIWindow { } public override func sendEvent(_ event: UIEvent) { - if !touchesVisible { - super.sendEvent(event) - return - } - - let touches = event.allTouches - - guard - let touches = touches, - touches.count > 0 - else { - cleanUpAllTouches() - super.sendEvent(event) - return - } - - for touch in touches { - let touchLocation = touch.location(in: self) - switch touch.phase { - case .began: - let touchView = newTouchView() - touchView.center = touchLocation - addSubview(touchView) - touchViews[touch] = touchView - - case .moved: - guard let touchView = touchViews[touch] else { - return + if touchesVisible { + let touches = event.allTouches + + guard + let touches = touches, + touches.count > 0 + else { + cleanUpAllTouches() + super.sendEvent(event) + return + } + + for touch in touches { + let touchLocation = touch.location(in: self) + switch touch.phase { + case .began: + let touchView = newTouchView() + touchView.center = touchLocation + addSubview(touchView) + touchViews[touch] = touchView + + case .moved: + guard let touchView = touchViews[touch] else { + return + } + touchView.center = touchLocation + + case .ended, .cancelled: + cleanupTouch(touch) + + default: + break } - touchView.center = touchLocation - - case .ended, .cancelled: - cleanupTouch(touch) - - default: - break } } From b634d2b844cdb4c024e505a6bfcff07e2ce0923c Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Tue, 6 Dec 2022 11:23:04 -0500 Subject: [PATCH 398/733] Add extra contrast on the touch views Felt like they needed to stand out just a bit more in light mode. --- .../MastodonUI/View/Window/TouchesVisibleWindow.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index bdde38ed0..586501f3b 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -10,9 +10,9 @@ import UIKit /// View that represents a single touch from the user. -fileprivate final class TouchView: UIView { +private final class TouchView: UIView { - private let blurView: UIVisualEffectView + private let blurView = UIVisualEffectView(effect: nil) override var frame: CGRect { didSet { @@ -21,9 +21,6 @@ fileprivate final class TouchView: UIView { } override init(frame: CGRect) { - let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight) - blurView = UIVisualEffectView(effect: blurEffect) - super.init(frame: frame) backgroundColor = .clear @@ -32,6 +29,10 @@ fileprivate final class TouchView: UIView { layer.borderColor = UIColor.white.cgColor layer.borderWidth = 2.0 + let blurEffect = traitCollection.userInterfaceStyle == .light ? + UIBlurEffect(style: .systemUltraThinMaterialDark) : + UIBlurEffect(style: .systemUltraThinMaterialLight) + blurView.effect = blurEffect addSubview(blurView) } From 6f0903466842835782610d0d720b00688f6475cb Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Tue, 6 Dec 2022 14:42:25 -0500 Subject: [PATCH 399/733] Tweak touch view border color --- .../MastodonUI/View/Window/TouchesVisibleWindow.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index 586501f3b..6eb7a4feb 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -23,13 +23,15 @@ private final class TouchView: UIView { override init(frame: CGRect) { super.init(frame: frame) + let isLightMode = traitCollection.userInterfaceStyle == .light + backgroundColor = .clear layer.masksToBounds = true layer.cornerCurve = .circular - layer.borderColor = UIColor.white.cgColor + layer.borderColor = isLightMode ? UIColor.gray.cgColor : UIColor.white.cgColor layer.borderWidth = 2.0 - let blurEffect = traitCollection.userInterfaceStyle == .light ? + let blurEffect = isLightMode ? UIBlurEffect(style: .systemUltraThinMaterialDark) : UIBlurEffect(style: .systemUltraThinMaterialLight) blurView.effect = blurEffect From 08ec662e221f9330ea6cd0c0abdcd37f71a53eea Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Wed, 7 Dec 2022 07:19:48 -0500 Subject: [PATCH 400/733] Fixing case where events aren't forwarded --- .../MastodonUI/View/Window/TouchesVisibleWindow.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index 6eb7a4feb..79888220b 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -115,10 +115,9 @@ public final class TouchesVisibleWindow: UIWindow { touchViews[touch] = touchView case .moved: - guard let touchView = touchViews[touch] else { - return + if let touchView = touchViews[touch] { + touchView.center = touchLocation } - touchView.center = touchLocation case .ended, .cancelled: cleanupTouch(touch) From 34b3d7d559e0fd7439d806a7a46e299d1ea32749 Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Wed, 7 Dec 2022 07:20:08 -0500 Subject: [PATCH 401/733] Fix file header --- .../Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift index 79888220b..8779e1ce7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Window/TouchesVisibleWindow.swift @@ -1,5 +1,5 @@ // -// File.swift +// TouchesVisibleWindow.swift // // // Created by Chase Carroll on 12/5/22. From 1020ca531a6766a73d19bb88c1a57074469a6e4a Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 15:41:33 +0100 Subject: [PATCH 402/733] feat: Implement status translation info footer and reversion --- .../TableviewCell/StatusTableViewCell.swift | 2 +- .../StatusThreadRootTableViewCell.swift | 2 +- .../Content/StatusView+Configuration.swift | 29 +++++---- .../View/Content/StatusView+ViewModel.swift | 10 +-- .../MastodonUI/View/Content/StatusView.swift | 62 ++++++++++++++++--- .../MastodonUI/View/Menu/MastodonMenu.swift | 2 +- 6 files changed, 76 insertions(+), 31 deletions(-) diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift index 3bb57302a..b8482c564 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift @@ -88,7 +88,7 @@ extension StatusTableViewCell { .store(in: &_disposeBag) statusView.viewModel - .$isTranslated + .$translatedFromLanguage .receive(on: DispatchQueue.main) .sink(receiveValue: { [weak self] _ in self?.invalidateIntrinsicContentSize() diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift index 5cc6f6596..73b700e27 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift @@ -83,7 +83,7 @@ extension StatusThreadRootTableViewCell { statusView.contentMetaText.textView.isSelectable = true statusView.viewModel - .$isTranslated + .$translatedFromLanguage .receive(on: DispatchQueue.main) .sink(receiveValue: { [weak self] _ in self?.invalidateIntrinsicContentSize() diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 498b77a5f..7b40b9609 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -55,18 +55,13 @@ extension StatusView { configurePoll(status: status) configureToolbar(status: status) configureFilter(status: status) - - status.$translatedContent + viewModel.originalStatus = status + [ + status.$translatedContent, + status.reblog?.$translatedContent + ].compactMap { $0 } + .last? .receive(on: DispatchQueue.main) - .compactMap { $0 } - .sink { [weak self] _ in - self?.configureTranslated(status: status) - } - .store(in: &disposeBag) - - status.reblog?.$translatedContent - .receive(on: DispatchQueue.main) - .compactMap { $0 } .sink { [weak self] _ in self?.configureTranslated(status: status) } @@ -247,6 +242,14 @@ extension StatusView { .store(in: &disposeBag) } + func revertTranslation() { + guard let originalStatus = viewModel.originalStatus else { return } + viewModel.translatedFromLanguage = nil + originalStatus.reblog?.translatedContent = nil + originalStatus.translatedContent = nil + configure(status: originalStatus) + } + func configureTranslated(status: Status) { let translatedContent: String? = { if let translatedContent = status.reblog?.translatedContent { @@ -267,7 +270,7 @@ extension StatusView { let content = MastodonContent(content: translatedContent, emojis: status.emojis.asDictionary) let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent - viewModel.isTranslated = true + viewModel.translatedFromLanguage = status.reblog?.language ?? status.language } catch { assertionFailure(error.localizedDescription) viewModel.content = PlaintextMetaContent(string: "") @@ -301,7 +304,7 @@ extension StatusView { let content = MastodonContent(content: status.content, emojis: status.emojis.asDictionary) let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent - viewModel.isTranslated = false + viewModel.translatedFromLanguage = nil } catch { assertionFailure(error.localizedDescription) viewModel.content = PlaintextMetaContent(string: "") diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index b56bba2e1..15919120c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -44,7 +44,7 @@ extension StatusView { @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false - @Published public var isTranslated = false + @Published public var translatedFromLanguage: String? @Published public var timestamp: Date? public var timestampFormatter: ((_ date: Date) -> String)? @@ -137,7 +137,7 @@ extension StatusView { isContentSensitive = false isMediaSensitive = false isSensitiveToggled = false - isTranslated = false + translatedFromLanguage = nil activeFilters = [] filterContext = nil @@ -586,7 +586,7 @@ extension StatusView.ViewModel { $isBookmark ) let publishersThree = Publishers.CombineLatest( - $isTranslated, + $translatedFromLanguage, $language ) @@ -598,7 +598,7 @@ extension StatusView.ViewModel { .sink { tupleOne, tupleTwo, tupleThree in let (authorName, isMyself) = tupleOne let (isMuting, isBlocking, isBookmark) = tupleTwo - let (isTranslated, language) = tupleThree + let (translatedFromLanguage, language) = tupleThree guard let name = authorName?.string else { statusView.authorView.menuButton.menu = nil @@ -611,7 +611,7 @@ extension StatusView.ViewModel { isBlocking: isBlocking, isMyself: isMyself, isBookmarking: isBookmark, - isTranslated: isTranslated, + isTranslated: translatedFromLanguage != nil, statusLanguage: language ) let (menu, actions) = authorView.setupAuthorMenu(menuContext: menuContext) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index bd901b08a..2838bbd85 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -176,6 +176,37 @@ public final class StatusView: UIView { indicatorView.stopAnimating() return indicatorView }() + private let translatedInfoLabel = UILabel() + lazy var translatedInfoView: UIView = { + let containerView = UIView() + + let revertButton = UIButton() + revertButton.setTitle("Show Original", for: .normal) + revertButton.setTitleColor(Asset.Colors.brand.color, for: .normal) + revertButton.addAction(UIAction { [weak self] _ in + self?.revertTranslation() + }, for: .touchUpInside) + + [containerView, translatedInfoLabel, revertButton].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + } + + [translatedInfoLabel, revertButton].forEach { + containerView.addSubview($0) + } + + NSLayoutConstraint.activate([ + containerView.heightAnchor.constraint(equalToConstant: 20), + translatedInfoLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + translatedInfoLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16), + revertButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + revertButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16) + ]) + + containerView.isHidden = true + + return containerView + }() // toolbar let actionToolbarAdaptiveMarginContainerView = AdaptiveMarginContainerView() @@ -217,6 +248,7 @@ public final class StatusView: UIView { setMediaDisplay(isDisplay: false) setPollDisplay(isDisplay: false) setFilterHintLabelDisplay(isDisplay: false) + setupTranslationIndicator() } public override init(frame: CGRect) { @@ -275,16 +307,6 @@ extension StatusView { // statusMetricView statusMetricView.delegate = self - - // status translation - viewModel.$isTranslated.sink { [weak self] isTranslated in - guard - let self = self, - let status = self.viewModel.originalStatus - else { return } - self.configureTranslated(status: status) - } - .store(in: &disposeBag) } } @@ -448,6 +470,9 @@ extension StatusView.Style { statusView.filterHintLabel.centerXAnchor.constraint(equalTo: statusView.containerStackView.centerXAnchor), statusView.filterHintLabel.centerYAnchor.constraint(equalTo: statusView.containerStackView.centerYAnchor), ]) + + // translated info + statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) } func inline(statusView: StatusView) { @@ -660,6 +685,23 @@ extension StatusView: MastodonMenuDelegate { } } +extension StatusView { + func setupTranslationIndicator() { + viewModel.$translatedFromLanguage + .receive(on: DispatchQueue.main) + .sink { [weak self] translatedFromLanguage in + guard let self = self else { return } + if let translatedFromLanguage = translatedFromLanguage { + self.translatedInfoLabel.text = String(format: "Translated from %@", Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? "Unknown") + self.translatedInfoView.isHidden = false + } else { + self.translatedInfoView.isHidden = true + } + } + .store(in: &disposeBag) + } +} + #if DEBUG import SwiftUI diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index e2e887db3..a09067adf 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -129,7 +129,7 @@ extension MastodonMenu { return deleteAction case let .translateStatus(context): let translateAction = BuiltAction( - title: String(format: "Translate from %@", context.language), + title: String(format: "Translate from %@", Locale.current.localizedString(forIdentifier: context.language) ?? "Unknown"), image: UIImage(systemName: "character.book.closed") ) { [weak delegate] in guard let delegate = delegate else { return } From dc174b4b6def76da44ac2f18863f6fc42e2f486e Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 15:52:38 +0100 Subject: [PATCH 403/733] feat: Implement translation progress indicator on status --- ...Provider+StatusTableViewCellDelegate.swift | 6 +++++ .../View/Content/StatusView+ViewModel.swift | 7 +++++- .../MastodonUI/View/Content/StatusView.swift | 24 +++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index c157b7086..be3f4dbab 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -360,6 +360,12 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte return } + if let cell = cell as? StatusTableViewCell { + DispatchQueue.main.async { + cell.statusView.viewModel.isCurrentlyTranslating = true + } + } + try await DataSourceFacade.responseToMenuAction( dependency: self, action: action, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 15919120c..eee318170 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -44,7 +44,12 @@ extension StatusView { @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false - @Published public var translatedFromLanguage: String? + + // Translation + @Published public var isCurrentlyTranslating = false + @Published public var translatedFromLanguage: String? { + didSet { isCurrentlyTranslating = false } + } @Published public var timestamp: Date? public var timestampFormatter: ((_ date: Date) -> String)? diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 2838bbd85..95ec5ff97 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -176,6 +176,12 @@ public final class StatusView: UIView { indicatorView.stopAnimating() return indicatorView }() + let isTranslatingLoadingView: UIActivityIndicatorView = { + let activityIndicatorView = UIActivityIndicatorView(style: .medium) + activityIndicatorView.hidesWhenStopped = true + activityIndicatorView.stopAnimating() + return activityIndicatorView + }() private let translatedInfoLabel = UILabel() lazy var translatedInfoView: UIView = { let containerView = UIView() @@ -199,8 +205,9 @@ public final class StatusView: UIView { containerView.heightAnchor.constraint(equalToConstant: 20), translatedInfoLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), translatedInfoLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16), - revertButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), - revertButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16) + revertButton.topAnchor.constraint(equalTo: containerView.topAnchor), + revertButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16), + revertButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) ]) containerView.isHidden = true @@ -472,6 +479,7 @@ extension StatusView.Style { ]) // translated info + statusView.containerStackView.addArrangedSubview(statusView.isTranslatingLoadingView) statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) } @@ -687,6 +695,18 @@ extension StatusView: MastodonMenuDelegate { extension StatusView { func setupTranslationIndicator() { + viewModel.$isCurrentlyTranslating + .receive(on: DispatchQueue.main) + .sink { [weak self] isTranslating in + switch isTranslating { + case true: + self?.isTranslatingLoadingView.startAnimating() + case false: + self?.isTranslatingLoadingView.stopAnimating() + } + } + .store(in: &disposeBag) + viewModel.$translatedFromLanguage .receive(on: DispatchQueue.main) .sink { [weak self] translatedFromLanguage in From bfdb2e2de9a4ef7d32d20fe650aefe78fe845599 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 16:00:18 +0100 Subject: [PATCH 404/733] chore: Update translated status footer style --- .../Sources/MastodonUI/View/Content/StatusView.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 95ec5ff97..4ac1735c6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -182,11 +182,17 @@ public final class StatusView: UIView { activityIndicatorView.stopAnimating() return activityIndicatorView }() - private let translatedInfoLabel = UILabel() + private let translatedInfoLabel: UILabel = { + let label = UILabel() + label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) + label.textColor = Asset.Colors.Label.secondary.color + return label + }() lazy var translatedInfoView: UIView = { let containerView = UIView() let revertButton = UIButton() + revertButton.titleLabel?.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .bold)) revertButton.setTitle("Show Original", for: .normal) revertButton.setTitleColor(Asset.Colors.brand.color, for: .normal) revertButton.addAction(UIAction { [weak self] _ in From 671b0e33f4d5c6065ee6696b103f19915d6b22dc Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 16:03:52 +0100 Subject: [PATCH 405/733] chore: Code-style adjustments --- .../MastodonUI/View/Content/NotificationView+ViewModel.swift | 4 ++-- .../MastodonUI/View/Content/StatusView+ViewModel.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index 11039875a..40c4f2870 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -209,13 +209,13 @@ extension NotificationView.ViewModel { $isTranslated ) ) - .sink { authorName, isMuting, isBlocking, comb2 in + .sink { authorName, isMuting, isBlocking, isMyselfIsTranslated in guard let name = authorName?.string else { notificationView.menuButton.menu = nil return } - let (isMyself, isTranslated) = comb2 + let (isMyself, isTranslated) = isMyselfIsTranslated let menuContext = NotificationView.AuthorMenuContext( name: name, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index eee318170..6432826c8 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -148,7 +148,7 @@ extension StatusView { filterContext = nil } - init() { + init() { // isReblogEnabled Publishers.CombineLatest( $visibility, From 7368e487af57a15707565ea63158f6634b80cb96 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 16:32:51 +0100 Subject: [PATCH 406/733] chore: Add L10n for status translation --- Localization/app.json | 11 ++++++++++- .../Generated/Strings.swift | 18 ++++++++++++++++++ .../Resources/Base.lproj/Localizable.strings | 7 ++++++- .../Resources/en.lproj/Localizable.strings | 7 ++++++- .../MastodonUI/View/Content/StatusView.swift | 4 ++-- .../MastodonUI/View/Menu/MastodonMenu.swift | 2 +- 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index c4a701948..63db5888b 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -91,7 +91,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +172,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index bafed05f6..38c21394a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -178,6 +178,14 @@ public enum L10n { public static func unblockDomain(_ p1: Any) -> String { return L10n.tr("Localizable", "Common.Controls.Actions.UnblockDomain", String(describing: p1), fallback: "Unblock %@") } + public enum TranslatePost { + /// Translate from %@ + public static func title(_ p1: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Actions.TranslatePost.Title", String(describing: p1), fallback: "Translate from %@") + } + /// Unknown + public static let unknownLanguage = L10n.tr("Localizable", "Common.Controls.Actions.TranslatePost.UnknownLanguage", fallback: "Unknown") + } } public enum Friendship { /// Block @@ -352,6 +360,16 @@ public enum L10n { /// URL public static let url = L10n.tr("Localizable", "Common.Controls.Status.Tag.Url", fallback: "URL") } + public enum Translation { + /// Show Original + public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Show Original") + /// Translated from %@ + public static func translatedFrom(_ p1: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), fallback: "Translated from %@") + } + /// Unknown + public static let unknownLanguage = L10n.tr("Localizable", "Common.Controls.Status.Translation.UnknownLanguage", fallback: "Unknown") + } public enum Visibility { /// Only mentioned user can see this post. public static let direct = L10n.tr("Localizable", "Common.Controls.Status.Visibility.Direct", fallback: "Only mentioned user can see this post.") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 5204a1176..8c4d03f6a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -59,6 +59,8 @@ Please check your internet connection."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; "Common.Controls.Friendship.Block" = "Block"; @@ -124,6 +126,9 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; +"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Replied to %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; @@ -467,4 +472,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 2a3f1efbf..e5f096962 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -59,6 +59,8 @@ Please check your internet connection."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; "Common.Controls.Friendship.Block" = "Block"; @@ -124,6 +126,9 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; +"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Replied to %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; @@ -461,4 +466,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 4ac1735c6..ba414638d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -193,7 +193,7 @@ public final class StatusView: UIView { let revertButton = UIButton() revertButton.titleLabel?.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .bold)) - revertButton.setTitle("Show Original", for: .normal) + revertButton.setTitle(L10n.Common.Controls.Status.Translation.showOriginal, for: .normal) revertButton.setTitleColor(Asset.Colors.brand.color, for: .normal) revertButton.addAction(UIAction { [weak self] _ in self?.revertTranslation() @@ -718,7 +718,7 @@ extension StatusView { .sink { [weak self] translatedFromLanguage in guard let self = self else { return } if let translatedFromLanguage = translatedFromLanguage { - self.translatedInfoLabel.text = String(format: "Translated from %@", Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? "Unknown") + self.translatedInfoLabel.text = L10n.Common.Controls.Status.Translation.translatedFrom(Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? L10n.Common.Controls.Status.Translation.unknownLanguage) self.translatedInfoView.isHidden = false } else { self.translatedInfoView.isHidden = true diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index a09067adf..6fd5df772 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -129,7 +129,7 @@ extension MastodonMenu { return deleteAction case let .translateStatus(context): let translateAction = BuiltAction( - title: String(format: "Translate from %@", Locale.current.localizedString(forIdentifier: context.language) ?? "Unknown"), + title: L10n.Common.Controls.Actions.TranslatePost.title(Locale.current.localizedString(forIdentifier: context.language) ?? L10n.Common.Controls.Actions.TranslatePost.unknownLanguage), image: UIImage(systemName: "character.book.closed") ) { [weak delegate] in guard let delegate = delegate else { return } From 8f3c755053cb454d6800c4c3d07679a406ba11f0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Dec 2022 16:46:16 +0100 Subject: [PATCH 407/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index ffdc32f92..f5e1d2139 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -45,7 +45,7 @@ "message": "Bitte aktiviere den Zugriff auf die Fotobibliothek, um das Foto zu speichern." }, "delete_post": { - "title": "Bist du dir sicher, dass du diesen Beitrag löschen möchtest?", + "title": "Beiträge löschen", "message": "Bist du dir sicher, dass du diesen Beitrag löschen willst?" }, "clean_cache": { @@ -83,7 +83,7 @@ "share_post": "Beitrag teilen", "open_in_safari": "In Safari öffnen", "open_in_browser": "Im Browser anzeigen", - "find_people": "Finde Personen zum Folgen", + "find_people": "Personen zum Folgen finden", "manually_search": "Stattdessen manuell suchen", "skip": "Überspringen", "reply": "Antworten", @@ -197,7 +197,7 @@ }, "loader": { "load_missing_posts": "Fehlende Beiträge laden", - "loading_missing_posts": "Lade fehlende Beiträge...", + "loading_missing_posts": "Fehlende Beiträge werden geladen …", "show_more_replies": "Weitere Antworten anzeigen" }, "header": { @@ -257,7 +257,7 @@ "search_servers_or_enter_url": "Suche nach einer Community oder gib eine URL ein" }, "empty_state": { - "finding_servers": "Verfügbare Server werden gesucht...", + "finding_servers": "Verfügbare Server werden gesucht …", "bad_network": "Beim Laden der Daten ist etwas schief gelaufen. Überprüfe deine Internetverbindung.", "no_results": "Keine Ergebnisse" } @@ -358,7 +358,7 @@ "offline": "Offline", "new_posts": "Neue Beiträge anzeigen", "published": "Veröffentlicht!", - "Publishing": "Beitrag wird veröffentlicht...", + "Publishing": "Beitrag wird veröffentlicht …", "accessibility": { "logo_label": "Logo-Button", "logo_hint": "Zum Scrollen nach oben tippen und zum vorherigen Ort erneut tippen" @@ -386,14 +386,14 @@ "photo": "Foto", "video": "Video", "attachment_broken": "Dieses %s scheint defekt zu sein und\nkann nicht auf Mastodon hochgeladen werden.", - "description_photo": "Für Menschen mit Sehbehinderung beschreiben...", - "description_video": "Für Menschen mit Sehbehinderung beschreiben...", + "description_photo": "Für Menschen mit Sehbehinderung beschreiben …", + "description_video": "Für Menschen mit Sehbehinderung beschreiben …", "load_failed": "Laden fehlgeschlagen", "upload_failed": "Upload fehlgeschlagen", "can_not_recognize_this_media_attachment": "Medienanhang wurde nicht erkannt", "attachment_too_large": "Anhang zu groß", - "compressing_state": "Komprimieren...", - "server_processing_state": "Serververarbeitung..." + "compressing_state": "wird komprimiert …", + "server_processing_state": "Serververarbeitung …" }, "poll": { "duration_time": "Dauer: %s", @@ -408,7 +408,7 @@ "the_poll_has_empty_option": "Die Umfrage hat eine leere Option" }, "content_warning": { - "placeholder": "Schreibe eine Inhaltswarnung hier..." + "placeholder": "Hier eine Inhaltswarnung schreiben …" }, "visibility": { "public": "Öffentlich", @@ -428,7 +428,7 @@ "disable_content_warning": "Inhaltswarnung ausschalten", "post_visibility_menu": "Sichtbarkeitsmenü", "post_options": "Beitragsoptionen", - "posting_as": "Posten als %s" + "posting_as": "Veröffentlichen als %s" }, "keyboard": { "discard_post": "Beitrag verwerfen", @@ -726,9 +726,9 @@ "followed_tags": { "title": "Gefolgte Hashtags", "header": { - "posts": "Posts", + "posts": "Beiträge", "participants": "Teilnehmer*innen", - "posts_today": "Posts heute" + "posts_today": "Beiträge heute" }, "actions": { "follow": "Folgen", From 0e6b6062895574aa1e1436704164c59ed1985f41 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Dec 2022 16:46:17 +0100 Subject: [PATCH 408/733] New translations Intents.strings (German) --- .../Intents/input/de.lproj/Intents.strings | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings index fd3fbd40f..5d0056766 100644 --- a/Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings @@ -1,12 +1,12 @@ -"16wxgf" = "Auf Mastodon posten"; +"16wxgf" = "Auf Mastodon veröffentlichen"; "751xkl" = "Textinhalt"; -"CsR7G2" = "Auf Mastodon posten"; +"CsR7G2" = "Auf Mastodon veröffentlichen"; -"HZSGTr" = "Welcher Inhalt soll gepostet werden?"; +"HZSGTr" = "Welcher Inhalt soll veröffentlicht werden?"; -"HdGikU" = "Posten fehlgeschlagen"; +"HdGikU" = "Veröffentlichen fehlgeschlagen"; "KDNTJ4" = "Fehlerursache"; From da3c9a42ecb0cd542c9825ba517c2f68a885d8b3 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 17:03:09 +0100 Subject: [PATCH 409/733] fix: Don't make isCurrentlyTranslating depend on translatedFromLanguage --- .../MastodonUI/View/Content/StatusView+Configuration.swift | 3 +++ .../MastodonUI/View/Content/StatusView+ViewModel.swift | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 7b40b9609..f31430fbb 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -262,6 +262,7 @@ extension StatusView { guard let translatedContent = translatedContent else { + viewModel.isCurrentlyTranslating = false return } @@ -271,6 +272,7 @@ extension StatusView { let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent viewModel.translatedFromLanguage = status.reblog?.language ?? status.language + viewModel.isCurrentlyTranslating = false } catch { assertionFailure(error.localizedDescription) viewModel.content = PlaintextMetaContent(string: "") @@ -305,6 +307,7 @@ extension StatusView { let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent viewModel.translatedFromLanguage = nil + viewModel.isCurrentlyTranslating = false } catch { assertionFailure(error.localizedDescription) viewModel.content = PlaintextMetaContent(string: "") diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 6432826c8..f45c07ea6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -47,9 +47,7 @@ extension StatusView { // Translation @Published public var isCurrentlyTranslating = false - @Published public var translatedFromLanguage: String? { - didSet { isCurrentlyTranslating = false } - } + @Published public var translatedFromLanguage: String? @Published public var timestamp: Date? public var timestampFormatter: ((_ date: Date) -> String)? @@ -143,6 +141,7 @@ extension StatusView { isMediaSensitive = false isSensitiveToggled = false translatedFromLanguage = nil + isCurrentlyTranslating = false activeFilters = [] filterContext = nil From fda3ae1516f5bb699941f1d5fcbba7e79281dfaf Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 7 Dec 2022 17:10:32 +0100 Subject: [PATCH 410/733] chore: Update translated footer alignment --- .../Sources/MastodonUI/View/Content/StatusView.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index ba414638d..7d7f41aa9 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -208,7 +208,7 @@ public final class StatusView: UIView { } NSLayoutConstraint.activate([ - containerView.heightAnchor.constraint(equalToConstant: 20), + containerView.heightAnchor.constraint(equalToConstant: 24), translatedInfoLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), translatedInfoLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16), revertButton.topAnchor.constraint(equalTo: containerView.topAnchor), @@ -469,6 +469,10 @@ extension StatusView.Style { statusView.pollStatusDotLabel.setContentHuggingPriority(.defaultHigh + 1, for: .horizontal) statusView.pollCountdownLabel.setContentHuggingPriority(.defaultLow, for: .horizontal) statusView.pollVoteButton.setContentHuggingPriority(.defaultHigh + 3, for: .horizontal) + + // translated info + statusView.containerStackView.addArrangedSubview(statusView.isTranslatingLoadingView) + statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) // action toolbar statusView.actionToolbarAdaptiveMarginContainerView.contentView = statusView.actionToolbarContainer @@ -483,10 +487,6 @@ extension StatusView.Style { statusView.filterHintLabel.centerXAnchor.constraint(equalTo: statusView.containerStackView.centerXAnchor), statusView.filterHintLabel.centerYAnchor.constraint(equalTo: statusView.containerStackView.centerYAnchor), ]) - - // translated info - statusView.containerStackView.addArrangedSubview(statusView.isTranslatingLoadingView) - statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) } func inline(statusView: StatusView) { From d2d981ab0ef2d781cf2a65ae50bb2eb8255efc28 Mon Sep 17 00:00:00 2001 From: Chase Carroll Date: Fri, 9 Dec 2022 09:18:56 -0500 Subject: [PATCH 411/733] Fix broken CCPoint conversion --- ...aHostToMediaPreviewViewControllerAnimatedTransitioning.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index ace6048c5..23a3664f3 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -534,7 +534,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { let scaleTransform = CGAffineTransform(scaleX: (itemWidth / size.width), y: (itemHeight / size.height)) let scaledOffset = transitionItem.touchOffset.apply(transform: scaleTransform) - let center = transitionView.convert(transitionView.center, to: nil) + let center = transitionView.convert(CGPoint(x: transitionView.bounds.midX, y: transitionView.bounds.midY), to: nil) snapshot.center = (center + (translation + (transitionItem.touchOffset - scaledOffset))).point snapshot.bounds = CGRect(origin: CGPoint.zero, size: CGSize(width: itemWidth, height: itemHeight)) transitionItem.touchOffset = scaledOffset From 58dcadf6422bb91bbc4fd625d0a2de956a937090 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 9 Dec 2022 16:12:13 +0100 Subject: [PATCH 412/733] feat: Implement error-handling for translation --- Localization/app.json | 5 +++ .../Provider/DataSourceFacade+Status.swift | 16 ++++--- .../Provider/DataSourceFacade+Translate.swift | 42 ++++++++++++++----- .../Generated/Strings.swift | 8 ++++ .../Resources/Base.lproj/Localizable.strings | 3 ++ .../Resources/en.lproj/Localizable.strings | 3 ++ 6 files changed, 62 insertions(+), 15 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 63db5888b..d44e76e26 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index 9d83d1073..b28daf1b5 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -393,12 +393,18 @@ extension DataSourceFacade { alertController.addAction(cancelAction) dependency.present(alertController, animated: true) - case let .translateStatus(translationContext): + case .translateStatus: guard let status = menuContext.status else { return } - try await DataSourceFacade.translateStatus( - provider: dependency, - status: status - ) + do { + try await DataSourceFacade.translateStatus( + provider: dependency, + status: status + ) + } catch TranslationFailure.emptyOrInvalidResponse { + let alertController = UIAlertController(title: L10n.Common.Alerts.TranslationFailed.title, message: L10n.Common.Alerts.TranslationFailed.message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: L10n.Common.Alerts.TranslationFailed.button, style: .default)) + dependency.present(alertController, animated: true) + } } } // end func } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index 08557a4bf..ba2b1b86d 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -11,6 +11,10 @@ import CoreDataStack import MastodonCore extension DataSourceFacade { + enum TranslationFailure: Error { + case emptyOrInvalidResponse + } + public static func translateStatus( provider: UIViewController & NeedsDependency & AuthContextProvider, status: ManagedObjectRecord @@ -25,19 +29,37 @@ extension DataSourceFacade { } func translate(status: Status) async throws -> String? { - let value = try await provider.context - .apiService - .translateStatus( - statusID: status.id, - authenticationBox: provider.authContext.mastodonAuthenticationBox - ).value - return value.content - } + do { + let value = try await provider.context + .apiService + .translateStatus( + statusID: status.id, + authenticationBox: provider.authContext.mastodonAuthenticationBox + ).value + + guard let content = value.content else { + throw TranslationFailure.emptyOrInvalidResponse + } + + return content + } catch { + throw TranslationFailure.emptyOrInvalidResponse + } + } + + func translateAndApply(to status: Status) async throws { + do { + status.translatedContent = try await translate(status: status) + } catch { + status.translatedContent = nil + throw TranslationFailure.emptyOrInvalidResponse + } + } if let reblog = status.reblog { - reblog.translatedContent = try await translate(status: reblog) + try await translateAndApply(to: reblog) } else { - status.translatedContent = try await translate(status: status) + try await translateAndApply(to: status) } } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 38c21394a..504fee233 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -87,6 +87,14 @@ public enum L10n { /// Sign Up Failure public static let title = L10n.tr("Localizable", "Common.Alerts.SignUpFailure.Title", fallback: "Sign Up Failure") } + public enum TranslationFailed { + /// OK + public static let button = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Button", fallback: "OK") + /// Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported. + public static let message = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Message", fallback: "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported.") + /// Note + public static let title = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Title", fallback: "Note") + } public enum VoteFailure { /// The poll has ended public static let pollEnded = L10n.tr("Localizable", "Common.Alerts.VoteFailure.PollEnded", fallback: "The poll has ended") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 8c4d03f6a..3bf85eb4f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -22,6 +22,9 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; +"Common.Alerts.TranslationFailed.Title" = "Note"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Button" = "OK"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index e5f096962..eb8a76868 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -22,6 +22,9 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; +"Common.Alerts.TranslationFailed.Title" = "Note"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Button" = "OK"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; From ade1a7362118d0440d316b3669d620c3e116a9e8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 9 Dec 2022 18:54:04 +0100 Subject: [PATCH 413/733] New translations Localizable.stringsdict (Hebrew) --- .../input/he.lproj/Localizable.stringsdict | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict index bd6cea903..cbb9a9f30 100644 --- a/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict @@ -13,13 +13,13 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + התראה אחת שלא נקראה two - %ld unread notifications + שתי התראות שלא נקראו many %ld unread notifications other - %ld unread notifications + %ld התראות שלא נקראו a11y.plural.count.input_limit_exceeds @@ -468,13 +468,13 @@ NSStringFormatValueTypeKey ld one - 1y ago + לפני שנה two - %ldy ago + לפני שנתיים many %ldy ago other - %ldy ago + לפני %ld שנים date.month.ago.abbr @@ -488,13 +488,13 @@ NSStringFormatValueTypeKey ld one - 1M ago + לפני חודש two - %ldM ago + לפני חודשיים many %ldM ago other - %ldM ago + לפני %ld חודשים date.day.ago.abbr @@ -508,13 +508,13 @@ NSStringFormatValueTypeKey ld one - 1d ago + לפני יום two - %ldd ago + לפני יומיים many %ldd ago other - %ldd ago + לפני %ld ימים date.hour.ago.abbr @@ -528,9 +528,9 @@ NSStringFormatValueTypeKey ld one - 1h ago + לפני שעה two - %ldh ago + לפני שעתיים many %ldh ago other From 4d47e574c751170d47618ad3f10ba5e5f3228559 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 9 Dec 2022 21:40:02 +0100 Subject: [PATCH 414/733] New translations app.json (Hebrew) --- Localization/StringsConvertor/input/he.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index de337841c..48c9d7f31 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -56,8 +56,8 @@ "controls": { "actions": { "back": "Back", - "next": "Next", - "previous": "Previous", + "next": "הבא", + "previous": "הקודם", "open": "Open", "add": "Add", "remove": "Remove", From 06ae31e9ed532e3fb4fddbc22ebe35af9ab4fabc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 9 Dec 2022 21:40:03 +0100 Subject: [PATCH 415/733] New translations Localizable.stringsdict (Hebrew) --- .../input/he.lproj/Localizable.stringsdict | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict index cbb9a9f30..63ed25f8a 100644 --- a/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/he.lproj/Localizable.stringsdict @@ -534,7 +534,7 @@ many %ldh ago other - %ldh ago + לפני %ld שעות date.minute.ago.abbr @@ -548,13 +548,13 @@ NSStringFormatValueTypeKey ld one - 1m ago + לפני דקה two - %ldm ago + לפני שתי דקות many %ldm ago other - %ldm ago + לפני %ld דקות date.second.ago.abbr @@ -568,13 +568,13 @@ NSStringFormatValueTypeKey ld one - 1s ago + לפני שנייה two - %lds ago + לפני שתי שניות many %lds ago other - %lds ago + לפני %ld שניות From b02f12291fff5d0f23f5c814a908fae79ddce954 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 11 Dec 2022 05:21:17 +0100 Subject: [PATCH 416/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index f0454707a..92bf9a0c8 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -381,7 +381,7 @@ }, "content_input_placeholder": "Cho thế giới biết bạn đang nghĩ gì", "compose_action": "Đăng", - "replying_to_user": "trả lời %s", + "replying_to_user": "%s viết tiếp", "attachment": { "photo": "ảnh", "video": "video", From 2d9e9802156ebcc26c32a22a506b7d1afc2d989d Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 12 Dec 2022 16:41:13 +0100 Subject: [PATCH 417/733] feat: Implement /api/v2/instance to conditionally show Translation option --- Mastodon/Diffable/Status/StatusSection.swift | 2 + ...DiscoveryCommunityViewModel+Diffable.swift | 1 + .../DiscoveryPostsViewModel+Diffable.swift | 1 + .../HashtagTimelineViewModel+Diffable.swift | 1 + .../HomeTimelineViewModel+Diffable.swift | 1 + .../Bookmark/BookmarkViewModel+Diffable.swift | 1 + .../Favorite/FavoriteViewModel+Diffable.swift | 1 + .../UserTimelineViewModel+Diffable.swift | 1 + .../Thread/ThreadViewModel+Diffable.swift | 1 + .../CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../CoreData 6.xcdatamodel/contents | 259 ++++++++++++++++++ .../Entity/Mastodon/Instance.swift | 7 +- .../Extension/CoreDataStack/Instance.swift | 40 ++- .../Service/API/APIService+Instance.swift | 5 + .../APIService+CoreData+InstanceV2.swift | 69 +++++ .../Service/InstanceService.swift | 118 +++++--- .../API/Mastodon+API+V2+Instance.swift | 50 ++++ .../MastodonSDK/API/Mastodon+API.swift | 1 + .../Entity/Mastodon+Entity+InstanceV2.swift | 158 +++++++++++ .../Content/NotificationView+ViewModel.swift | 25 +- .../View/Content/StatusAuthorView.swift | 3 +- .../View/Content/StatusView+ViewModel.swift | 17 ++ 22 files changed, 722 insertions(+), 42 deletions(-) create mode 100644 MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents create mode 100644 MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+V2+Instance.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift diff --git a/Mastodon/Diffable/Status/StatusSection.swift b/Mastodon/Diffable/Status/StatusSection.swift index 38b8e641f..8ccb32c0c 100644 --- a/Mastodon/Diffable/Status/StatusSection.swift +++ b/Mastodon/Diffable/Status/StatusSection.swift @@ -27,6 +27,7 @@ extension StatusSection { static let logger = Logger(subsystem: "StatusSection", category: "logic") struct Configuration { + let context: AppContext let authContext: AuthContext weak var statusTableViewCellDelegate: StatusTableViewCellDelegate? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? @@ -250,6 +251,7 @@ extension StatusSection { statusView: cell.statusView ) + cell.statusView.viewModel.context = configuration.context cell.statusView.viewModel.authContext = configuration.authContext cell.configure( diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift index 64b4d3b6a..caa1f8460 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift @@ -18,6 +18,7 @@ extension DiscoveryCommunityViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift index afa0594d5..f36812538 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift @@ -18,6 +18,7 @@ extension DiscoveryPostsViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift index 8d8b0126a..c7c0a3bd7 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift @@ -20,6 +20,7 @@ extension HashtagTimelineViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index 29bff623b..ff3224d3d 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -22,6 +22,7 @@ extension HomeTimelineViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: timelineMiddleLoaderTableViewCellDelegate, diff --git a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift index 69075a8ce..bb9148687 100644 --- a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift @@ -17,6 +17,7 @@ extension BookmarkViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift index 3723dae5d..e0f741f62 100644 --- a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift @@ -17,6 +17,7 @@ extension FavoriteViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift index 863d7b44e..4992e653a 100644 --- a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift @@ -18,6 +18,7 @@ extension UserTimelineViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift index 834d478e6..8846c8b95 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift @@ -24,6 +24,7 @@ extension ThreadViewModel { tableView: tableView, context: context, configuration: StatusSection.Configuration( + context: context, authContext: authContext, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index 2145ac780..e660b0a08 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 5.xcdatamodel + CoreData 6.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents new file mode 100644 index 000000000..3249c5510 --- /dev/null +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift index cc21e8351..c11a92b76 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Instance.swift @@ -16,7 +16,8 @@ public final class Instance: NSManagedObject { @NSManaged public private(set) var updatedAt: Date @NSManaged public private(set) var configurationRaw: Data? - + @NSManaged public private(set) var configurationV2Raw: Data? + // MARK: one-to-many relationships @NSManaged public var authentications: Set } @@ -44,6 +45,10 @@ extension Instance { self.configurationRaw = configurationRaw } + public func update(configurationV2Raw: Data?) { + self.configurationV2Raw = configurationV2Raw + } + public func didUpdate(at networkDate: Date) { self.updatedAt = networkDate } diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift index 7e925b665..619abc91e 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift @@ -25,8 +25,42 @@ extension Instance { } extension Instance { - public var canFollowTags: Bool { - guard let majorVersionString = version?.split(separator: ".").first else { return false } - return Int(majorVersionString) == 4 // following Tags is support beginning with Mastodon v4.0.0 + public var configurationV2: Mastodon.Entity.V2.Instance.Configuration? { + guard let configurationRaw = configurationV2Raw else { return nil } + guard let configuration = try? JSONDecoder().decode(Mastodon.Entity.V2.Instance.Configuration.self, from: configurationRaw) else { + return nil + } + + return configuration + } + + static func encodeV2(configuration: Mastodon.Entity.V2.Instance.Configuration) -> Data? { + return try? JSONEncoder().encode(configuration) + } +} + +extension Instance { + public var canFollowTags: Bool { + version?.majorServerVersion(greaterThanOrEquals: 4) ?? false // following Tags is support beginning with Mastodon v4.0.0 + } +} + +extension String { + public func majorServerVersion(greaterThanOrEquals comparedVersion: Int) -> Bool { + guard + let majorVersionString = split(separator: ".").first, + let majorVersionInt = Int(majorVersionString) + else { return false } + + return majorVersionInt >= comparedVersion + } +} + +extension Instance { + var isTranslationEnabled: Bool { + if let configuration = configurationV2 { + return configuration.translation?.enabled == true + } + return false } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Instance.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Instance.swift index 93bfcf09a..eb39b5585 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Instance.swift @@ -20,4 +20,9 @@ extension APIService { return Mastodon.API.Instance.instance(session: session, domain: domain) } + public func instanceV2( + domain: String + ) -> AnyPublisher, Error> { + return Mastodon.API.V2.Instance.instance(session: session, domain: domain) + } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift new file mode 100644 index 000000000..17ebb5f55 --- /dev/null +++ b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift @@ -0,0 +1,69 @@ +import os.log +import Foundation +import CoreData +import CoreDataStack +import MastodonSDK + +extension APIService.CoreData { + + static func createOrMergeInstanceV2( + into managedObjectContext: NSManagedObjectContext, + domain: String, + entity: Mastodon.Entity.V2.Instance, + networkDate: Date, + log: Logger + ) -> (instance: Instance, isCreated: Bool) { + // fetch old mastodon user + let old: Instance? = { + let request = Instance.sortedFetchRequest + request.predicate = Instance.predicate(domain: domain) + request.fetchLimit = 1 + request.returnsObjectsAsFaults = false + do { + return try managedObjectContext.fetch(request).first + } catch { + assertionFailure(error.localizedDescription) + return nil + } + }() + + if let old = old { + APIService.CoreData.mergeV2( + instance: old, + entity: entity, + domain: domain, + networkDate: networkDate + ) + return (old, false) + } else { + let instance = Instance.insert( + into: managedObjectContext, + property: Instance.Property(domain: domain, version: entity.version) + ) + let configurationRaw = entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } + instance.update(configurationV2Raw: configurationRaw) + + return (instance, true) + } + } + +} + +extension APIService.CoreData { + + static func mergeV2( + instance: Instance, + entity: Mastodon.Entity.V2.Instance, + domain: String, + networkDate: Date + ) { + guard networkDate > instance.updatedAt else { return } + + let configurationRaw = entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } + instance.update(configurationV2Raw: configurationRaw) + instance.version = entity.version + + instance.didUpdate(at: networkDate) + } + +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift index 99ad6d0a2..02946ca6c 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift @@ -50,42 +50,18 @@ extension InstanceService { func updateInstance(domain: String) { guard let apiService = self.apiService else { return } apiService.instance(domain: domain) - .flatMap { response -> AnyPublisher, Error> in - let managedObjectContext = self.backgroundManagedObjectContext - return managedObjectContext.performChanges { - // get instance - let (instance, _) = APIService.CoreData.createOrMergeInstance( - into: managedObjectContext, - domain: domain, - entity: response.value, - networkDate: response.networkDate, - log: Logger(subsystem: "Update", category: "InstanceService") - ) - - // update relationship - let request = MastodonAuthentication.sortedFetchRequest - request.predicate = MastodonAuthentication.predicate(domain: domain) - request.returnsObjectsAsFaults = false - do { - let authentications = try managedObjectContext.fetch(request) - for authentication in authentications { - authentication.update(instance: instance) - } - } catch { - assertionFailure(error.localizedDescription) - } + .flatMap { [unowned self] response -> AnyPublisher in + if response.value.version?.majorServerVersion(greaterThanOrEquals: 4) == true { + return apiService.instanceV2(domain: domain) + .flatMap { return self.updateInstanceV2(domain: domain, response: $0) } + .eraseToAnyPublisher() + } else { + return self.updateInstance(domain: domain, response: response) } - .setFailureType(to: Error.self) - .tryMap { result -> Mastodon.Response.Content in - switch result { - case .success: - return response - case .failure(let error): - throw error - } - } - .eraseToAnyPublisher() } +// .flatMap { [unowned self] response -> AnyPublisher in +// return +// } .sink { [weak self] completion in guard let self = self else { return } switch completion { @@ -100,6 +76,80 @@ extension InstanceService { } .store(in: &disposeBag) } + + private func updateInstance(domain: String, response: Mastodon.Response.Content) -> AnyPublisher { + let managedObjectContext = self.backgroundManagedObjectContext + return managedObjectContext.performChanges { + // get instance + let (instance, _) = APIService.CoreData.createOrMergeInstance( + into: managedObjectContext, + domain: domain, + entity: response.value, + networkDate: response.networkDate, + log: Logger(subsystem: "Update", category: "InstanceService") + ) + + // update relationship + let request = MastodonAuthentication.sortedFetchRequest + request.predicate = MastodonAuthentication.predicate(domain: domain) + request.returnsObjectsAsFaults = false + do { + let authentications = try managedObjectContext.fetch(request) + for authentication in authentications { + authentication.update(instance: instance) + } + } catch { + assertionFailure(error.localizedDescription) + } + } + .setFailureType(to: Error.self) + .tryMap { result in + switch result { + case .success: + break + case .failure(let error): + throw error + } + } + .eraseToAnyPublisher() + } + + private func updateInstanceV2(domain: String, response: Mastodon.Response.Content) -> AnyPublisher { + let managedObjectContext = self.backgroundManagedObjectContext + return managedObjectContext.performChanges { + // get instance + let (instance, _) = APIService.CoreData.createOrMergeInstanceV2( + into: managedObjectContext, + domain: domain, + entity: response.value, + networkDate: response.networkDate, + log: Logger(subsystem: "Update", category: "InstanceService") + ) + + // update relationship + let request = MastodonAuthentication.sortedFetchRequest + request.predicate = MastodonAuthentication.predicate(domain: domain) + request.returnsObjectsAsFaults = false + do { + let authentications = try managedObjectContext.fetch(request) + for authentication in authentications { + authentication.update(instance: instance) + } + } catch { + assertionFailure(error.localizedDescription) + } + } + .setFailureType(to: Error.self) + .tryMap { result in + switch result { + case .success: + break + case .failure(let error): + throw error + } + } + .eraseToAnyPublisher() + } } public extension InstanceService { diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+V2+Instance.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+V2+Instance.swift new file mode 100644 index 000000000..e276fddba --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+V2+Instance.swift @@ -0,0 +1,50 @@ +import Foundation +import Combine + +extension Mastodon.API.V2.Instance { + + private static func instanceEndpointURL(domain: String) -> URL { + return Mastodon.API.endpointV2URL(domain: domain).appendingPathComponent("instance") + } + + /// Information about the server + /// + /// - Since: 4.0.0 + /// - Version: 4.0.0 + /// # Last Update + /// 2022/12/09 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/instance/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - Returns: `AnyPublisher` contains `Instance` nested in the response + public static func instance( + session: URLSession, + domain: String + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: instanceEndpointURL(domain: domain), + query: nil, + authorization: nil + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value: Mastodon.Entity.V2.Instance + + do { + value = try Mastodon.API.decode(type: Mastodon.Entity.V2.Instance.self, from: data, response: response) + } catch { + if let response = response as? HTTPURLResponse, 400 ..< 500 ~= response.statusCode { + // For example, AUTHORIZED_FETCH may result in authentication errors + value = Mastodon.Entity.V2.Instance(domain: domain) + } else { + throw error + } + } + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index a1eb47873..f85d50bd0 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -126,6 +126,7 @@ extension Mastodon.API.V2 { public enum Search { } public enum Suggestions { } public enum Media { } + public enum Instance { } } extension Mastodon.API { diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift new file mode 100644 index 000000000..05913ebe9 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift @@ -0,0 +1,158 @@ +import Foundation + +extension Mastodon.Entity.V2 { + /// Instance + /// + /// - Since: 4.0.0 + /// - Version: 4.0.3 + /// # Last Update + /// 2022/12/09 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/instance/) + public struct Instance: Codable { + + public let domain: String? + public let title: String + public let description: String + public let shortDescription: String? + public let email: String? + public let version: String? + public let languages: [String]? // (ISO 639 Part 1-5 language codes) + public let registrations: Mastodon.Entity.V2.Instance.Registrations? + public let approvalRequired: Bool? + public let invitesEnabled: Bool? + public let urls: Mastodon.Entity.Instance.InstanceURL? + public let statistics: Mastodon.Entity.Instance.Statistics? + + public let thumbnail: Thumbnail? + public let contactAccount: Mastodon.Entity.Account? + public let rules: [Mastodon.Entity.Instance.Rule]? + + // https://github.com/mastodon/mastodon/pull/16485 + public let configuration: Configuration? + + public init(domain: String, approvalRequired: Bool? = nil) { + self.domain = domain + self.title = domain + self.description = "" + self.shortDescription = nil + self.email = "" + self.version = nil + self.languages = nil + self.registrations = nil + self.approvalRequired = approvalRequired + self.invitesEnabled = nil + self.urls = nil + self.statistics = nil + self.thumbnail = nil + self.contactAccount = nil + self.rules = nil + self.configuration = nil + } + + enum CodingKeys: String, CodingKey { + case domain + case title + case description + case shortDescription = "short_description" + case email + case version + case languages + case registrations + case approvalRequired = "approval_required" + case invitesEnabled = "invites_enabled" + case urls + case statistics = "stats" + + case thumbnail + case contactAccount = "contact_account" + case rules + + case configuration + } + } +} + +extension Mastodon.Entity.V2.Instance { + public struct Configuration: Codable { + public let statuses: Mastodon.Entity.Instance.Configuration.Statuses? + public let mediaAttachments: Mastodon.Entity.Instance.Configuration.MediaAttachments? + public let polls: Mastodon.Entity.Instance.Configuration.Polls? + public let translation: Mastodon.Entity.V2.Instance.Configuration.Translation? + + enum CodingKeys: String, CodingKey { + case statuses + case mediaAttachments = "media_attachments" + case polls + case translation + } + } +} + +extension Mastodon.Entity.V2.Instance { + public struct Registrations: Codable { + public let enabled: Bool + } +} + +extension Mastodon.Entity.V2.Instance.Configuration { + public struct Translation: Codable { + public let enabled: Bool + } +} + +extension Mastodon.Entity.V2.Instance { + public struct Thumbnail: Codable { + public let url: String? + } +} + +//extension Mastodon.Entity.V2.Instance { +// public struct Statuses: Codable { +// public let maxCharacters: Int +// public let maxMediaAttachments: Int +// public let charactersReservedPerURL: Int +// +// enum CodingKeys: String, CodingKey { +// case maxCharacters = "max_characters" +// case maxMediaAttachments = "max_media_attachments" +// case charactersReservedPerURL = "characters_reserved_per_url" +// } +// } +// +// public struct MediaAttachments: Codable { +// public let supportedMIMETypes: [String] +// public let imageSizeLimit: Int +// public let imageMatrixLimit: Int +// public let videoSizeLimit: Int +// public let videoFrameRateLimit: Int +// public let videoMatrixLimit: Int +// +// enum CodingKeys: String, CodingKey { +// case supportedMIMETypes = "supported_mime_types" +// case imageSizeLimit = "image_size_limit" +// case imageMatrixLimit = "image_matrix_limit" +// case videoSizeLimit = "video_size_limit" +// case videoFrameRateLimit = "video_frame_rate_limit" +// case videoMatrixLimit = "video_matrix_limit" +// } +// } +// +// public struct Polls: Codable { +// public let maxOptions: Int +// public let maxCharactersPerOption: Int +// public let minExpiration: Int +// public let maxExpiration: Int +// +// enum CodingKeys: String, CodingKey { +// case maxOptions = "max_options" +// case maxCharactersPerOption = "max_characters_per_option" +// case minExpiration = "min_expiration" +// case maxExpiration = "max_expiration" +// } +// } +// +// public struct Translation: Codable { +// public let enabled: Bool +// } +//} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index 40c4f2870..ed038f47f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -23,7 +23,8 @@ extension NotificationView { public var objects = Set() let logger = Logger(subsystem: "NotificationView", category: "ViewModel") - + + @Published public var context: AppContext? @Published public var authContext: AuthContext? @Published public var type: MastodonNotificationType? @@ -57,6 +58,9 @@ extension NotificationView.ViewModel { bindAuthorMenu(notificationView: notificationView) bindFollowRequest(notificationView: notificationView) + $context + .assign(to: \.context, on: notificationView.statusView.viewModel) + .store(in: &disposeBag) $authContext .assign(to: \.authContext, on: notificationView.statusView.viewModel) .store(in: &disposeBag) @@ -209,7 +213,7 @@ extension NotificationView.ViewModel { $isTranslated ) ) - .sink { authorName, isMuting, isBlocking, isMyselfIsTranslated in + .sink { [weak self] authorName, isMuting, isBlocking, isMyselfIsTranslated in guard let name = authorName?.string else { notificationView.menuButton.menu = nil return @@ -217,12 +221,29 @@ extension NotificationView.ViewModel { let (isMyself, isTranslated) = isMyselfIsTranslated + lazy var instanceConfigurationV2: Mastodon.Entity.V2.Instance.Configuration? = { + guard + let self = self, + let context = self.context, + let authContext = self.authContext + else { return nil } + + var configuration: Mastodon.Entity.V2.Instance.Configuration? = nil + context.managedObjectContext.performAndWait { + guard let authentication = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext) + else { return } + configuration = authentication.instance?.configurationV2 + } + return configuration + }() + let menuContext = NotificationView.AuthorMenuContext( name: name, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself, isBookmarking: false, // no bookmark action display for notification item + isTranslationEnabled: instanceConfigurationV2?.translation?.enabled == true, isTranslated: isTranslated, statusLanguage: "" ) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index c930a7b66..ef40ab7fc 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -150,6 +150,7 @@ extension StatusAuthorView { public let isMyself: Bool public let isBookmarking: Bool + public let isTranslationEnabled: Bool public let isTranslated: Bool public let statusLanguage: String? } @@ -158,7 +159,7 @@ extension StatusAuthorView { var actions = [MastodonMenu.Action]() if !menuContext.isMyself { - if let statusLanguage = menuContext.statusLanguage, !menuContext.isTranslated { + if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled, !menuContext.isTranslated { actions.append( .translateStatus(.init(language: statusLanguage)) ) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index f45c07ea6..09995677c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -27,6 +27,7 @@ extension StatusView { let logger = Logger(subsystem: "StatusView", category: "ViewModel") + public var context: AppContext? public var authContext: AuthContext? public var originalStatus: Status? @@ -609,12 +610,28 @@ extension StatusView.ViewModel { return } + lazy var instanceConfigurationV2: Mastodon.Entity.V2.Instance.Configuration? = { + guard + let context = self.context, + let authContext = self.authContext + else { return nil } + + var configuration: Mastodon.Entity.V2.Instance.Configuration? = nil + context.managedObjectContext.performAndWait { + guard let authentication = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext) + else { return } + configuration = authentication.instance?.configurationV2 + } + return configuration + }() + let menuContext = StatusAuthorView.AuthorMenuContext( name: name, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself, isBookmarking: isBookmark, + isTranslationEnabled: instanceConfigurationV2?.translation?.enabled == true, isTranslated: translatedFromLanguage != nil, statusLanguage: language ) From cb2765fd0f9a0a9093d82517971dda92d6cdc62c Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 12 Dec 2022 16:43:54 +0100 Subject: [PATCH 418/733] chore: Replace instance by server in strings --- Localization/app.json | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++-- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/en.lproj/Localizable.strings | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index d44e76e26..82f1f7516 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -54,7 +54,7 @@ }, "translation_failed": { "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported.", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", "button": "OK" } }, diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 504fee233..69ff5e97f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -90,8 +90,8 @@ public enum L10n { public enum TranslationFailed { /// OK public static let button = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Button", fallback: "OK") - /// Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported. - public static let message = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Message", fallback: "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported.") + /// Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported. + public static let message = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Message", fallback: "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.") /// Note public static let title = L10n.tr("Localizable", "Common.Alerts.TranslationFailed.Title", fallback: "Note") } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 3bf85eb4f..2ec8830b0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -23,7 +23,7 @@ Please check your internet connection."; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; "Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Button" = "OK"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index eb8a76868..9afcd60d9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -23,7 +23,7 @@ Please check your internet connection."; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; "Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this instance or this instance is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Button" = "OK"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; From 8f32e1a80effb21968dc63c2cbe6452a5918a019 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 12 Dec 2022 16:53:41 +0100 Subject: [PATCH 419/733] Update MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift Co-authored-by: Jed Fox --- .../MastodonSDK/Entity/Mastodon+Entity+Translation.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift index b8993de9e..f500453f1 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Translation.swift @@ -1,5 +1,5 @@ // -// File.swift +// Mastodon+Entity+Translation.swift // // // Created by Marcus Kida on 02.12.22. From 85f4c454a329f1b8962e6ddca9a39d6350c27df5 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 13 Dec 2022 06:54:58 +0100 Subject: [PATCH 420/733] chore: Refactor code and apply PR improvements --- .../Provider/DataSourceFacade+Translate.swift | 66 ++++++++++--------- .../Extension/CoreDataStack/Instance.swift | 9 ++- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index ba2b1b86d..fc95cb018 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -10,13 +10,15 @@ import CoreData import CoreDataStack import MastodonCore +typealias Provider = UIViewController & NeedsDependency & AuthContextProvider + extension DataSourceFacade { enum TranslationFailure: Error { case emptyOrInvalidResponse } public static func translateStatus( - provider: UIViewController & NeedsDependency & AuthContextProvider, + provider: Provider, status: ManagedObjectRecord ) async throws { let selectionFeedbackGenerator = await UISelectionFeedbackGenerator() @@ -28,38 +30,40 @@ extension DataSourceFacade { return } - func translate(status: Status) async throws -> String? { - do { - let value = try await provider.context - .apiService - .translateStatus( - statusID: status.id, - authenticationBox: provider.authContext.mastodonAuthenticationBox - ).value - - guard let content = value.content else { - throw TranslationFailure.emptyOrInvalidResponse - } - - return content - } catch { - throw TranslationFailure.emptyOrInvalidResponse - } - } - - func translateAndApply(to status: Status) async throws { - do { - status.translatedContent = try await translate(status: status) - } catch { - status.translatedContent = nil - throw TranslationFailure.emptyOrInvalidResponse - } - } - if let reblog = status.reblog { - try await translateAndApply(to: reblog) + try await translateAndApply(provider: provider, status: reblog) } else { - try await translateAndApply(to: status) + try await translateAndApply(provider: provider, status: status) + } + } +} + +private extension DataSourceFacade { + static func translateStatus(provider: Provider, status: Status) async throws -> String? { + do { + let value = try await provider.context + .apiService + .translateStatus( + statusID: status.id, + authenticationBox: provider.authContext.mastodonAuthenticationBox + ).value + + guard let content = value.content else { + throw TranslationFailure.emptyOrInvalidResponse + } + + return content + } catch { + throw TranslationFailure.emptyOrInvalidResponse + } + } + + static func translateAndApply(provider: Provider, status: Status) async throws { + do { + status.translatedContent = try await translateStatus(provider: provider, status: status) + } catch { + status.translatedContent = nil + throw TranslationFailure.emptyOrInvalidResponse } } } diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift index 619abc91e..f54f4514d 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift @@ -26,8 +26,13 @@ extension Instance { extension Instance { public var configurationV2: Mastodon.Entity.V2.Instance.Configuration? { - guard let configurationRaw = configurationV2Raw else { return nil } - guard let configuration = try? JSONDecoder().decode(Mastodon.Entity.V2.Instance.Configuration.self, from: configurationRaw) else { + guard + let configurationRaw = configurationV2Raw, + let configuration = try? JSONDecoder().decode( + Mastodon.Entity.V2.Instance.Configuration.self, + from: configurationRaw + ) + else { return nil } From 110a89f4993b04d79c22ebfb94d1253fe359f061 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 13 Dec 2022 07:07:08 +0100 Subject: [PATCH 421/733] fix: AppContext is missing for some StatusView.ViewModels --- Mastodon/Diffable/Notification/NotificationSection.swift | 1 + Mastodon/Diffable/Report/ReportSection.swift | 1 + Mastodon/Diffable/Search/SearchResultSection.swift | 1 + 3 files changed, 3 insertions(+) diff --git a/Mastodon/Diffable/Notification/NotificationSection.swift b/Mastodon/Diffable/Notification/NotificationSection.swift index 387affbc7..0271aac20 100644 --- a/Mastodon/Diffable/Notification/NotificationSection.swift +++ b/Mastodon/Diffable/Notification/NotificationSection.swift @@ -76,6 +76,7 @@ extension NotificationSection { viewModel: NotificationTableViewCell.ViewModel, configuration: Configuration ) { + cell.notificationView.viewModel.context = context cell.notificationView.viewModel.authContext = configuration.authContext StatusSection.setupStatusPollDataSource( diff --git a/Mastodon/Diffable/Report/ReportSection.swift b/Mastodon/Diffable/Report/ReportSection.swift index ba3c5525a..4c8fd4345 100644 --- a/Mastodon/Diffable/Report/ReportSection.swift +++ b/Mastodon/Diffable/Report/ReportSection.swift @@ -107,6 +107,7 @@ extension ReportSection { statusView: cell.statusView ) + cell.statusView.viewModel.context = context cell.statusView.viewModel.authContext = configuration.authContext cell.configure( diff --git a/Mastodon/Diffable/Search/SearchResultSection.swift b/Mastodon/Diffable/Search/SearchResultSection.swift index 8a5d7e75f..e4dcad891 100644 --- a/Mastodon/Diffable/Search/SearchResultSection.swift +++ b/Mastodon/Diffable/Search/SearchResultSection.swift @@ -104,6 +104,7 @@ extension SearchResultSection { statusView: cell.statusView ) + cell.statusView.viewModel.context = context cell.statusView.viewModel.authContext = configuration.authContext cell.configure( From 903d789b53d5c344f1a6366b048f780a73ff4534 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 13 Dec 2022 07:07:56 +0100 Subject: [PATCH 422/733] chore: Remove unused code --- .../Entity/Mastodon+Entity+InstanceV2.swift | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift index 05913ebe9..d662c24c2 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+InstanceV2.swift @@ -106,53 +106,3 @@ extension Mastodon.Entity.V2.Instance { public let url: String? } } - -//extension Mastodon.Entity.V2.Instance { -// public struct Statuses: Codable { -// public let maxCharacters: Int -// public let maxMediaAttachments: Int -// public let charactersReservedPerURL: Int -// -// enum CodingKeys: String, CodingKey { -// case maxCharacters = "max_characters" -// case maxMediaAttachments = "max_media_attachments" -// case charactersReservedPerURL = "characters_reserved_per_url" -// } -// } -// -// public struct MediaAttachments: Codable { -// public let supportedMIMETypes: [String] -// public let imageSizeLimit: Int -// public let imageMatrixLimit: Int -// public let videoSizeLimit: Int -// public let videoFrameRateLimit: Int -// public let videoMatrixLimit: Int -// -// enum CodingKeys: String, CodingKey { -// case supportedMIMETypes = "supported_mime_types" -// case imageSizeLimit = "image_size_limit" -// case imageMatrixLimit = "image_matrix_limit" -// case videoSizeLimit = "video_size_limit" -// case videoFrameRateLimit = "video_frame_rate_limit" -// case videoMatrixLimit = "video_matrix_limit" -// } -// } -// -// public struct Polls: Codable { -// public let maxOptions: Int -// public let maxCharactersPerOption: Int -// public let minExpiration: Int -// public let maxExpiration: Int -// -// enum CodingKeys: String, CodingKey { -// case maxOptions = "max_options" -// case maxCharactersPerOption = "max_characters_per_option" -// case minExpiration = "min_expiration" -// case maxExpiration = "max_expiration" -// } -// } -// -// public struct Translation: Codable { -// public let enabled: Bool -// } -//} From 518941b10cfbd969b712ebc253575bc5f0b600f2 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 13 Dec 2022 07:10:08 +0100 Subject: [PATCH 423/733] chore: Codestyle changes --- .../Extension/CoreDataStack/Instance.swift | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift index f54f4514d..eebb16be4 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Instance.swift @@ -48,6 +48,13 @@ extension Instance { public var canFollowTags: Bool { version?.majorServerVersion(greaterThanOrEquals: 4) ?? false // following Tags is support beginning with Mastodon v4.0.0 } + + var isTranslationEnabled: Bool { + if let configuration = configurationV2 { + return configuration.translation?.enabled == true + } + return false + } } extension String { @@ -60,12 +67,3 @@ extension String { return majorVersionInt >= comparedVersion } } - -extension Instance { - var isTranslationEnabled: Bool { - if let configuration = configurationV2 { - return configuration.translation?.enabled == true - } - return false - } -} From 2edeae81fa3d39ccf377646e643022270f5f07ad Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 13 Dec 2022 15:02:22 +0100 Subject: [PATCH 424/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 680ba2ac1..df25db90d 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -95,7 +95,7 @@ }, "tabs": { "home": "Hafan", - "search_and_explore": "Search and Explore", + "search_and_explore": "Chwilio ac Archwilio", "notifications": "Hysbysiadau", "profile": "Proffil" }, @@ -724,15 +724,15 @@ "title": "Tudalnodau" }, "followed_tags": { - "title": "Followed Tags", + "title": "Tagiau a Ddilynwyd", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "postiadau", + "participants": "cyfranwyr", + "posts_today": "postiadau heddiw" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Dilyn", + "unfollow": "Dad-ddilyn" } } } From 47024bfb4d4c7128ffadb6157b66696f285b9ac2 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 13 Dec 2022 10:07:37 -0500 Subject: [PATCH 425/733] =?UTF-8?q?Differentiate=20between=20=E2=80=9CMy?= =?UTF-8?q?=20followers=E2=80=9D=20and=20other=20accounts=20followers=20in?= =?UTF-8?q?=20i18n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StringsConvertor/input/Base.lproj/app.json | 9 ++++++--- Localization/app.json | 9 ++++++--- .../Header/ProfileHeaderViewController.swift | 3 +++ .../Profile/Header/ProfileHeaderViewModel.swift | 1 + .../Header/View/ProfileHeaderView+ViewModel.swift | 14 ++++++++++++++ .../Scene/Profile/ProfileViewController.swift | 3 +++ .../MastodonLocalization/Generated/Strings.swift | 12 +++++++++--- .../Resources/Base.lproj/Localizable.strings | 9 ++++++--- .../View/Content/ProfileCardView+ViewModel.swift | 15 ++++++++++++++- .../Control/ProfileStatusDashboardMeterView.swift | 1 - .../View/Control/ProfileStatusDashboardView.swift | 4 ---- 11 files changed, 62 insertions(+), 18 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index c4a701948..12ad3263e 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -444,9 +444,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "add_row": "Add Row", diff --git a/Localization/app.json b/Localization/app.json index c4a701948..12ad3263e 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -444,9 +444,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "add_row": "Add Row", diff --git a/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift b/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift index 7ca819b41..55e73a1e8 100644 --- a/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift +++ b/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift @@ -153,6 +153,9 @@ extension ProfileHeaderViewController { viewModel.$relationshipActionOptionSet .assign(to: \.relationshipActionOptionSet, on: profileHeaderView.viewModel) .store(in: &disposeBag) + viewModel.$isMyself + .assign(to: \.isMyself, on: profileHeaderView.viewModel) + .store(in: &disposeBag) viewModel.$isEditing .assign(to: \.isEditing, on: profileHeaderView.viewModel) .store(in: &disposeBag) diff --git a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift index c66789cca..3025907e0 100644 --- a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift +++ b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift @@ -30,6 +30,7 @@ final class ProfileHeaderViewModel { @Published var user: MastodonUser? @Published var relationshipActionOptionSet: RelationshipActionOptionSet = .none + @Published var isMyself = false @Published var isEditing = false @Published var isUpdating = false diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift index 5095d7ac0..c5389958a 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift @@ -48,6 +48,7 @@ extension ProfileHeaderView { @Published var relationshipActionOptionSet: RelationshipActionOptionSet = .none @Published var isRelationshipActionButtonHidden = false + @Published var isMyself = false init() { $relationshipActionOptionSet @@ -189,6 +190,19 @@ extension ProfileHeaderView.ViewModel { } .store(in: &disposeBag) // dashboard + $isMyself + .sink { isMyself in + if isMyself { + view.statusDashboardView.postDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myPosts + view.statusDashboardView.followingDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myFollowing + view.statusDashboardView.followersDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myFollowers + } else { + view.statusDashboardView.postDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherPosts + view.statusDashboardView.followingDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherFollowing + view.statusDashboardView.followersDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherFollowers + } + } + .store(in: &disposeBag) $statusesCount .sink { count in let text = count.flatMap { MastodonMetricFormatter().string(from: $0) } ?? "-" diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 1ee13457b..7e133e012 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -311,6 +311,9 @@ extension ProfileViewController { viewModel.$isUpdating .assign(to: \.isUpdating, on: headerViewModel) .store(in: &disposeBag) + viewModel.relationshipViewModel.$isMyself + .assign(to: \.isMyself, on: headerViewModel) + .store(in: &disposeBag) viewModel.relationshipViewModel.$optionSet .map { $0 ?? .none } .assign(to: \.relationshipActionOptionSet, on: headerViewModel) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index bafed05f6..94815ea8b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -754,11 +754,17 @@ public enum L10n { } public enum Dashboard { /// followers - public static let followers = L10n.tr("Localizable", "Scene.Profile.Dashboard.Followers", fallback: "followers") + public static let myFollowers = L10n.tr("Localizable", "Scene.Profile.Dashboard.MyFollowers", fallback: "followers") /// following - public static let following = L10n.tr("Localizable", "Scene.Profile.Dashboard.Following", fallback: "following") + public static let myFollowing = L10n.tr("Localizable", "Scene.Profile.Dashboard.MyFollowing", fallback: "following") /// posts - public static let posts = L10n.tr("Localizable", "Scene.Profile.Dashboard.Posts", fallback: "posts") + public static let myPosts = L10n.tr("Localizable", "Scene.Profile.Dashboard.MyPosts", fallback: "posts") + /// followers + public static let otherFollowers = L10n.tr("Localizable", "Scene.Profile.Dashboard.OtherFollowers", fallback: "followers") + /// following + public static let otherFollowing = L10n.tr("Localizable", "Scene.Profile.Dashboard.OtherFollowing", fallback: "following") + /// posts + public static let otherPosts = L10n.tr("Localizable", "Scene.Profile.Dashboard.OtherPosts", fallback: "posts") } public enum Fields { /// Add Row diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 5204a1176..5174a9760 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -270,9 +270,12 @@ 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.Followers" = "followers"; -"Scene.Profile.Dashboard.Following" = "following"; -"Scene.Profile.Dashboard.Posts" = "posts"; +"Scene.Profile.Dashboard.MyFollowers" = "followers"; +"Scene.Profile.Dashboard.MyFollowing" = "following"; +"Scene.Profile.Dashboard.MyPosts" = "posts"; +"Scene.Profile.Dashboard.OtherFollowers" = "followers"; +"Scene.Profile.Dashboard.OtherFollowing" = "following"; +"Scene.Profile.Dashboard.OtherPosts" = "posts"; "Scene.Profile.Fields.AddRow" = "Add Row"; "Scene.Profile.Fields.Placeholder.Content" = "Content"; "Scene.Profile.Fields.Placeholder.Label" = "Label"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift index 55d270f74..beb7680a8 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift @@ -43,7 +43,7 @@ extension ProfileCardView { @Published public var isMuting = false @Published public var isBlocking = false @Published public var isBlockedBy = false - + @Published public var groupedAccessibilityLabel = "" @Published public var familiarFollowers: Mastodon.Entity.FamiliarFollowers? @@ -173,6 +173,19 @@ extension ProfileCardView.ViewModel { } private func bindDashboard(view: ProfileCardView) { + relationshipViewModel.$isMyself + .sink { isMyself in + if isMyself { + view.statusDashboardView.postDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myPosts + view.statusDashboardView.followingDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myFollowing + view.statusDashboardView.followersDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.myFollowers + } else { + view.statusDashboardView.postDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherPosts + view.statusDashboardView.followingDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherFollowing + view.statusDashboardView.followersDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.otherFollowers + } + } + .store(in: &disposeBag) $statusesCount .receive(on: DispatchQueue.main) .sink { count in diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardMeterView.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardMeterView.swift index 0c9d243c2..08f84da33 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardMeterView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardMeterView.swift @@ -29,7 +29,6 @@ public final class ProfileStatusDashboardMeterView: UIView { let label = UILabel() label.font = .systemFont(ofSize: 13, weight: .regular) label.textColor = Asset.Colors.Label.primary.color - label.text = L10n.Scene.Profile.Dashboard.posts label.textAlignment = .center if UIView.isZoomedMode { label.adjustsFontSizeToFitWidth = true diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardView.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardView.swift index a45e8ef6a..3be447292 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ProfileStatusDashboardView.swift @@ -66,10 +66,6 @@ extension ProfileStatusDashboardView { containerStackView.setCustomSpacing(spacing + 2, after: followingDashboardMeterView) containerStackView.addArrangedSubview(followersDashboardMeterView) - postDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.posts - followingDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.following - followersDashboardMeterView.textLabel.text = L10n.Scene.Profile.Dashboard.followers - [postDashboardMeterView, followingDashboardMeterView, followersDashboardMeterView].forEach { meterView in let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer tapGestureRecognizer.addTarget(self, action: #selector(ProfileStatusDashboardView.tapGestureRecognizerHandler(_:))) From 855f626c42fbb843090fc821a1b41830c6b63a9b Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 14 Dec 2022 09:35:45 +0100 Subject: [PATCH 426/733] fix: Make translatedContent a transient CoreData property --- .../Protocol/Provider/DataSourceFacade+Translate.swift | 5 +++-- .../CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents | 3 ++- .../Sources/CoreDataStack/Entity/Mastodon/Status.swift | 8 +++++++- .../View/Content/StatusView+Configuration.swift | 8 ++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index fc95cb018..cd4cec4b0 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -60,9 +60,10 @@ private extension DataSourceFacade { static func translateAndApply(provider: Provider, status: Status) async throws { do { - status.translatedContent = try await translateStatus(provider: provider, status: status) + let translated = try await translateStatus(provider: provider, status: status) + status.update(translatedContent: translated) } catch { - status.translatedContent = nil + status.update(translatedContent: nil) throw TranslationFailure.emptyOrInvalidResponse } } diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents index 3249c5510..30e89ccb4 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -201,6 +201,7 @@ + diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift index 1f46a6ce1..3bd1df794 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift @@ -100,7 +100,8 @@ public final class Status: NSManagedObject { // sourcery: autoUpdatableObject @NSManaged public private(set) var revealedAt: Date? - @Published public var translatedContent: String? + // sourcery: autoUpdatableObject + @NSManaged public private(set) var translatedContent: String? } extension Status { @@ -497,6 +498,11 @@ extension Status: AutoUpdatableObject { self.revealedAt = revealedAt } } + public func update(translatedContent: String?) { + if self.translatedContent != translatedContent { + self.translatedContent = translatedContent + } + } public func update(attachments: [MastodonAttachment]) { if self.attachments != attachments { self.attachments = attachments diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index f31430fbb..cc369f972 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -57,8 +57,8 @@ extension StatusView { configureFilter(status: status) viewModel.originalStatus = status [ - status.$translatedContent, - status.reblog?.$translatedContent + status.publisher(for: \.translatedContent), + status.reblog?.publisher(for: \.translatedContent) ].compactMap { $0 } .last? .receive(on: DispatchQueue.main) @@ -245,8 +245,8 @@ extension StatusView { func revertTranslation() { guard let originalStatus = viewModel.originalStatus else { return } viewModel.translatedFromLanguage = nil - originalStatus.reblog?.translatedContent = nil - originalStatus.translatedContent = nil + originalStatus.reblog?.update(translatedContent: nil) + originalStatus.update(translatedContent: nil) configure(status: originalStatus) } From f530d109d33c351643273f96e6dc3bfc5fa8bf30 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 14 Dec 2022 09:51:15 +0100 Subject: [PATCH 427/733] chore: Address PR codestyle feedback --- .../APIService+CoreData+InstanceV2.swift | 54 +++++++++++-------- .../Service/InstanceService.swift | 14 ++--- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift index 17ebb5f55..19e188133 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/CoreData/APIService+CoreData+InstanceV2.swift @@ -6,17 +6,33 @@ import MastodonSDK extension APIService.CoreData { - static func createOrMergeInstanceV2( - into managedObjectContext: NSManagedObjectContext, - domain: String, - entity: Mastodon.Entity.V2.Instance, - networkDate: Date, - log: Logger + public struct PersistContext { + public let domain: String + public let entity: Mastodon.Entity.V2.Instance + public let networkDate: Date + public let log: Logger + + public init( + domain: String, + entity: Mastodon.Entity.V2.Instance, + networkDate: Date, + log: Logger + ) { + self.domain = domain + self.entity = entity + self.networkDate = networkDate + self.log = log + } + } + + static func createOrMergeInstance( + in managedObjectContext: NSManagedObjectContext, + context: PersistContext ) -> (instance: Instance, isCreated: Bool) { // fetch old mastodon user let old: Instance? = { let request = Instance.sortedFetchRequest - request.predicate = Instance.predicate(domain: domain) + request.predicate = Instance.predicate(domain: context.domain) request.fetchLimit = 1 request.returnsObjectsAsFaults = false do { @@ -28,19 +44,17 @@ extension APIService.CoreData { }() if let old = old { - APIService.CoreData.mergeV2( + APIService.CoreData.merge( instance: old, - entity: entity, - domain: domain, - networkDate: networkDate + context: context ) return (old, false) } else { let instance = Instance.insert( into: managedObjectContext, - property: Instance.Property(domain: domain, version: entity.version) + property: Instance.Property(domain: context.domain, version: context.entity.version) ) - let configurationRaw = entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } + let configurationRaw = context.entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } instance.update(configurationV2Raw: configurationRaw) return (instance, true) @@ -51,19 +65,17 @@ extension APIService.CoreData { extension APIService.CoreData { - static func mergeV2( + static func merge( instance: Instance, - entity: Mastodon.Entity.V2.Instance, - domain: String, - networkDate: Date + context: PersistContext ) { - guard networkDate > instance.updatedAt else { return } + guard context.networkDate > instance.updatedAt else { return } - let configurationRaw = entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } + let configurationRaw = context.entity.configuration.flatMap { Instance.encodeV2(configuration: $0) } instance.update(configurationV2Raw: configurationRaw) - instance.version = entity.version + instance.version = context.entity.version - instance.didUpdate(at: networkDate) + instance.didUpdate(at: context.networkDate) } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift index 02946ca6c..0745e2f37 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/InstanceService.swift @@ -118,12 +118,14 @@ extension InstanceService { let managedObjectContext = self.backgroundManagedObjectContext return managedObjectContext.performChanges { // get instance - let (instance, _) = APIService.CoreData.createOrMergeInstanceV2( - into: managedObjectContext, - domain: domain, - entity: response.value, - networkDate: response.networkDate, - log: Logger(subsystem: "Update", category: "InstanceService") + let (instance, _) = APIService.CoreData.createOrMergeInstance( + in: managedObjectContext, + context: .init( + domain: domain, + entity: response.value, + networkDate: response.networkDate, + log: Logger(subsystem: "Update", category: "InstanceService") + ) ) // update relationship From 6329f100461d26719cf58eca26c16e2916e2d01f Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 14 Dec 2022 10:33:50 +0100 Subject: [PATCH 428/733] chore: Move translated info directly below translated text --- .../Sources/MastodonUI/View/Content/StatusView.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 7d7f41aa9..751e7929d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -431,6 +431,10 @@ extension StatusView.Style { statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView) statusView.containerStackView.setCustomSpacing(16, after: statusView.contentMetaText.textView) + // translated info + statusView.containerStackView.addArrangedSubview(statusView.isTranslatingLoadingView) + statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) + statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false statusView.containerStackView.addSubview(statusView.spoilerOverlayView) statusView.contentContainer.pinTo(to: statusView.spoilerOverlayView) @@ -470,10 +474,6 @@ extension StatusView.Style { statusView.pollCountdownLabel.setContentHuggingPriority(.defaultLow, for: .horizontal) statusView.pollVoteButton.setContentHuggingPriority(.defaultHigh + 3, for: .horizontal) - // translated info - statusView.containerStackView.addArrangedSubview(statusView.isTranslatingLoadingView) - statusView.containerStackView.addArrangedSubview(statusView.translatedInfoView) - // action toolbar statusView.actionToolbarAdaptiveMarginContainerView.contentView = statusView.actionToolbarContainer statusView.actionToolbarAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin From 3b325945e277e1cfe125e718d8bee351d2352979 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:05 +0100 Subject: [PATCH 429/733] New translations app.json (Slovenian) --- .../StringsConvertor/input/sl.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 6825c1094..3224a7d5d 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Počisti predpomnilnik", "message": "Uspešno počiščem predpomnilnik %s." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blokiraj %s", "unblock_domain": "Odblokiraj %s", "settings": "Nastavitve", - "delete": "Izbriši" + "delete": "Izbriši", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Domov", @@ -168,6 +177,11 @@ "private": "Samo sledilci osebe lahko vidijo to objavo.", "private_from_me": "Samo moji sledilci lahko vidijo to objavo.", "direct": "Samo omenjeni uporabnik lahko vidi to objavo." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 9bc0a63828b525917e1c976a4edece0c9e093c10 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:07 +0100 Subject: [PATCH 430/733] New translations app.json (Chinese Traditional) --- .../input/zh-Hant.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 0a8ab8e2d..40a309e9a 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "清除快取", "message": "成功清除 %s 快取。" + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "封鎖 %s", "unblock_domain": "解除封鎖 %s", "settings": "設定", - "delete": "刪除" + "delete": "刪除", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "首頁", @@ -168,6 +177,11 @@ "private": "只有他們的跟隨者能看到此嘟文。", "private_from_me": "只有我的跟隨者能看到此嘟文。", "direct": "只有被提及的使用者能看到此嘟文。" + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 6dfc9090df0529431edb8b1a563eb16afd37f51d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:08 +0100 Subject: [PATCH 431/733] New translations app.json (Vietnamese) --- .../StringsConvertor/input/vi.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 92bf9a0c8..4befeeb18 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Xóa bộ nhớ đệm", "message": "Đã xóa %s bộ nhớ đệm." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Chặn %s", "unblock_domain": "Bỏ chặn %s", "settings": "Cài đặt", - "delete": "Xóa" + "delete": "Xóa", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Bảng tin", @@ -168,6 +177,11 @@ "private": "Chỉ người theo dõi của họ có thể thấy tút này.", "private_from_me": "Chỉ người theo dõi tôi có thể thấy tút này.", "direct": "Chỉ người được nhắc đến có thể thấy tút." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From cef6eae657ec9d1ade8f4beab6a9b69212ec6a79 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:09 +0100 Subject: [PATCH 432/733] New translations app.json (Kabyle) --- .../StringsConvertor/input/kab.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 709a52d0f..ac440de6e 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Sfeḍ tuffirt", "message": "Yettwasfeḍ %s n tkatut tuffirt akken iwata." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Sewḥel %s", "unblock_domain": "Serreḥ i %s", "settings": "Iɣewwaṛen", - "delete": "Kkes" + "delete": "Kkes", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Agejdan", @@ -168,6 +177,11 @@ "private": "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a.", "private_from_me": "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a.", "direct": "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 2c27d9a1f519cef26ed4658eaf4016c0fa264fb8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:10 +0100 Subject: [PATCH 433/733] New translations app.json (Korean) --- .../StringsConvertor/input/ko.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index dfe94cd69..ebc1d922c 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "캐시 삭제", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s 차단하기", "unblock_domain": "%s 차단 해제", "settings": "설정", - "delete": "삭제" + "delete": "삭제", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "홈", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 6d4d147520f30aec19f1f38adfeca32bfd880cb7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:11 +0100 Subject: [PATCH 434/733] New translations app.json (Swedish) --- .../StringsConvertor/input/sv.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index cf8abbca5..68f47af4f 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Rensa cache", "message": "Rensade %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blockera %s", "unblock_domain": "Avblockera %s", "settings": "Inställningar", - "delete": "Radera" + "delete": "Radera", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Hem", @@ -168,6 +177,11 @@ "private": "Endast deras följare kan se detta inlägg.", "private_from_me": "Bara mina följare kan se det här inlägget.", "direct": "Endast omnämnda användare kan se detta inlägg." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From add871fc6a156cd340822100ed6ce39b948a3740 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:12 +0100 Subject: [PATCH 435/733] New translations app.json (French) --- .../StringsConvertor/input/fr.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index c644965ee..1815a5052 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Vider le cache", "message": "Cache de %s effacé avec succès." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloquer %s", "unblock_domain": "Débloquer %s", "settings": "Paramètres", - "delete": "Supprimer" + "delete": "Supprimer", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Accueil", @@ -168,6 +177,11 @@ "private": "Seul·e·s leurs abonné·e·s peuvent voir ce message.", "private_from_me": "Seul·e·s mes abonné·e·s peuvent voir ce message.", "direct": "Seul·e l’utilisateur·rice mentionnée peut voir ce message." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From dcbfdcffbd7e733698d36a32be39ca5f14fce778 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:13 +0100 Subject: [PATCH 436/733] New translations app.json (Turkish) --- .../StringsConvertor/input/tr.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 74a138304..6ea40e510 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Önbelleği Temizle", "message": "%s boyutunda önbellek temizlendi." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s kişisini engelle", "unblock_domain": "%s kişisinin engelini kaldır", "settings": "Ayarlar", - "delete": "Sil" + "delete": "Sil", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Ana Sayfa", @@ -168,6 +177,11 @@ "private": "Sadece gönderi sahibinin takipçileri bu gönderiyi görebilir.", "private_from_me": "Sadece benim takipçilerim bu gönderiyi görebilir.", "direct": "Sadece bahsedilen kullanıcı bu gönderiyi görebilir." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 40d2e3a7cad74603e9e803bf33820eab2167b386 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:14 +0100 Subject: [PATCH 437/733] New translations app.json (Czech) --- .../StringsConvertor/input/cs.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index cfa49cd7c..1b63d6a44 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Vyčistit mezipaměť", "message": "Úspěšně vyčištěno %s mezipaměti." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blokovat %s", "unblock_domain": "Odblokovat %s", "settings": "Nastavení", - "delete": "Smazat" + "delete": "Smazat", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Domů", @@ -168,6 +177,11 @@ "private": "Pouze jejich sledující mohou vidět tento příspěvek.", "private_from_me": "Pouze moji sledující mohou vidět tento příspěvek.", "direct": "Pouze zmíněný uživatel může vidět tento příspěvek." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From ddd348c54a5a76f0524584156656f9f5773ae41a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:15 +0100 Subject: [PATCH 438/733] New translations app.json (Ukrainian) --- .../StringsConvertor/input/uk.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 62be7ac9d..a53eb143a 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Очистити кеш", "message": "%s успішно очищено." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Блокувати %s", "unblock_domain": "Розблокувати %s", "settings": "Налаштування", - "delete": "Видалити" + "delete": "Видалити", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Головна", @@ -168,6 +177,11 @@ "private": "Лише їхні підписники можуть бачити цю публікацію.", "private_from_me": "Тільки мої підписники можуть бачити цю публікацію.", "direct": "Тільки згаданий користувач може бачити цю публікацію." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 05ac703ff390f8f8bd98397dc61d9fb926a169bc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:16 +0100 Subject: [PATCH 439/733] New translations app.json (Scottish Gaelic) --- .../StringsConvertor/input/gd.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 57f5c2c14..2e3408b6c 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Falamhaich an tasgadan", "message": "Chaidh %s a thasgadan fhalamhachadh." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bac %s", "unblock_domain": "Dì-bhac %s", "settings": "Roghainnean", - "delete": "Sguab às" + "delete": "Sguab às", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Dachaigh", @@ -168,6 +177,11 @@ "private": "Chan fhaic ach an luchd-leantainn aca am post seo.", "private_from_me": "Chan fhaic ach an luchd-leantainn agam am post seo.", "direct": "Chan fhaic ach an cleachdaiche air an dugadh iomradh am post seo." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 86b2cb779f926156151e381f006bf64a3aeeaec6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:17 +0100 Subject: [PATCH 440/733] New translations app.json (Romanian) --- .../StringsConvertor/input/ro.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 2ce7d060f..db34a1e6e 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Acasă", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From c90126162326ebb025df84e82b9d8e88b5bdef32 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:18 +0100 Subject: [PATCH 441/733] New translations app.json (Spanish) --- .../StringsConvertor/input/es.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index a2709f3ff..e8eb2572c 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Limpiar Caché", "message": "Se han limpiado con éxito %s de caché." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloquear %s", "unblock_domain": "Desbloquear %s", "settings": "Configuración", - "delete": "Borrar" + "delete": "Borrar", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Inicio", @@ -168,6 +177,11 @@ "private": "Sólo sus seguidores pueden ver este mensaje.", "private_from_me": "Sólo mis seguidores pueden ver este mensaje.", "direct": "Sólo el usuario mencionado puede ver este mensaje." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 28e35247c77818ada485f4694131293759344a1d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:20 +0100 Subject: [PATCH 442/733] New translations app.json (Arabic) --- .../StringsConvertor/input/ar.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index f70dc116a..f3c034355 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "مَحوُ ذاكِرَةِ التَّخزينِ المُؤقَّت", "message": "مُحِيَ ما مَساحَتُهُ %s مِن ذاكِرَةِ التَّخزينِ المُؤقَّت بِنجاح." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "حظر %s", "unblock_domain": "رفع الحظر عن %s", "settings": "الإعدادات", - "delete": "حذف" + "delete": "حذف", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "الرَّئِيسَة", @@ -168,6 +177,11 @@ "private": "فَقَطْ مُتابِعينَهُم مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور.", "private_from_me": "فَقَطْ مُتابِعيني أنَا مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور.", "direct": "المُستخدمِونَ المُشارِ إليهم فَقَطْ مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 94aeef0ae20afb875d2394ec92474a88d8ade8e1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:21 +0100 Subject: [PATCH 443/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 84ae80bd5..64791cc01 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Neteja la memòria cau", "message": "S'ha netejat correctament la memòria cau de %s." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloqueja %s", "unblock_domain": "Desbloqueja %s", "settings": "Configuració", - "delete": "Suprimeix" + "delete": "Suprimeix", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Inici", @@ -168,6 +177,11 @@ "private": "Només els seus seguidors poden veure aquesta publicació.", "private_from_me": "Només els meus seguidors poden veure aquesta publicació.", "direct": "Només l'usuari mencionat pot veure aquesta publicació." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From eeb10889664cdc48d144d6506296bd411c304d25 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:22 +0100 Subject: [PATCH 444/733] New translations app.json (Danish) --- .../StringsConvertor/input/da.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 85940744c..3283645cb 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 7d435e9ff14aac2afd1e3cb73ce9bb8f928d46ff Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:23 +0100 Subject: [PATCH 445/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index f5e1d2139..e4c5ab91b 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Zwischenspeicher leeren", "message": "%s erfolgreich aus dem Cache gelöscht." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s blockieren", "unblock_domain": "Blockierung von %s aufheben", "settings": "Einstellungen", - "delete": "Löschen" + "delete": "Löschen", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Startseite", @@ -168,6 +177,11 @@ "private": "Nur die, die dem Autor folgen, können diesen Beitrag sehen.", "private_from_me": "Nur die, die mir folgen, können diesen Beitrag sehen.", "direct": "Nur erwähnte Benutzer können diesen Beitrag sehen." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 012fa87c37237042c931539c2f3aedf61d6a90bd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:24 +0100 Subject: [PATCH 446/733] New translations app.json (Basque) --- .../StringsConvertor/input/eu.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 6a6c5a5c2..9c4dc6a4b 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Garbitu cache-a", "message": "Behar bezala garbitu da %s cache-a." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blokeatu %s", "unblock_domain": "Desblokeatu %s", "settings": "Ezarpenak", - "delete": "Ezabatu" + "delete": "Ezabatu", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Hasiera", @@ -168,6 +177,11 @@ "private": "Beren jarraitzaileek soilik ikus dezakete bidalketa hau.", "private_from_me": "Nire jarraitzaileek soilik ikus dezakete bidalketa hau.", "direct": "Aipatutako erabiltzaileek soilik ikus dezakete bidalketa hau." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 332f725a5012f2d737e0d384b4e7dfc24e5c4d90 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:25 +0100 Subject: [PATCH 447/733] New translations app.json (Finnish) --- .../StringsConvertor/input/fi.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index e70326bf2..3d1ca2422 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Puhdista välimuisti", "message": "%s välimuisti tyhjennetty onnistuneesti." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Estä %s", "unblock_domain": "Poista esto %s", "settings": "Asetukset", - "delete": "Poista" + "delete": "Poista", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Koti", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 34f005b1d0540acc19a2ffd28f4d8d78781f2916 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:26 +0100 Subject: [PATCH 448/733] New translations app.json (Italian) --- .../StringsConvertor/input/it.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index dedc71b8c..c6136b4b6 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Pulisci la cache", "message": "Cache %s pulita con successo." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blocca %s", "unblock_domain": "Sblocca %s", "settings": "Impostazioni", - "delete": "Elimina" + "delete": "Elimina", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Inizio", @@ -168,6 +177,11 @@ "private": "Solo i loro seguaci possono vedere questo post.", "private_from_me": "Solo i miei seguaci possono vedere questo post.", "direct": "Solo l'utente menzionato può vedere questo post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From d4b81af87b7c23cd93728e9959b3f30ff3bbd12d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:27 +0100 Subject: [PATCH 449/733] New translations app.json (Japanese) --- .../StringsConvertor/input/ja.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 2642bdf71..d36810c9b 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "キャッシュを消去", "message": "%sのキャッシュを消去しました。" + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%sをブロック", "unblock_domain": "%sのブロックを解除", "settings": "設定", - "delete": "削除" + "delete": "削除", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "ホーム", @@ -168,6 +177,11 @@ "private": "この投稿はフォロワーに限り見ることができます。", "private_from_me": "この投稿はフォロワーに限り見ることができます。", "direct": "この投稿はメンションされたユーザーに限り見ることができます。" + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 9d13f0b1e06ce9808af3d346bf1580cf5714f232 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:28 +0100 Subject: [PATCH 450/733] New translations app.json (Dutch) --- .../StringsConvertor/input/nl.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index d38fff6c1..9640aafb5 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Cache-geheugen Wissen", "message": "Cache-geheugen (%s) succesvol gewist." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blokkeer %s", "unblock_domain": "Deblokkeer %s", "settings": "Instellingen", - "delete": "Verwijder" + "delete": "Verwijder", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Start", @@ -168,6 +177,11 @@ "private": "Alleen hun volgers kunnen dit bericht zien.", "private_from_me": "Alleen mijn volgers kunnen dit bericht zien.", "direct": "Alleen de vermelde persoon kan dit bericht zien." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 123e1f6a65a21e8302bfc5f3e7bed2fea0429e27 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:29 +0100 Subject: [PATCH 451/733] New translations app.json (Portuguese) --- .../StringsConvertor/input/pt.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 85940744c..3283645cb 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 040be7300704ab08447584e6d439fb1674612e2d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:30 +0100 Subject: [PATCH 452/733] New translations app.json (Russian) --- .../StringsConvertor/input/ru.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 0c906b579..19a37db92 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Очистка кэша", "message": "Успешно очищено %s кэша." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Заблокировать %s", "unblock_domain": "Разблокировать %s", "settings": "Настройки", - "delete": "Удалить" + "delete": "Удалить", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Главная", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From a30f2679cc538e4eaab17c969307054dc1c73e2e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:31 +0100 Subject: [PATCH 453/733] New translations app.json (Chinese Simplified) --- .../input/zh-Hans.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 6bf633d09..95da0f20f 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "清除缓存", "message": "成功清除 %s 缓存。" + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "屏蔽 %s", "unblock_domain": "解除屏蔽 %s", "settings": "设置", - "delete": "删除" + "delete": "删除", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "主页", @@ -168,6 +177,11 @@ "private": "只有作者的关注者才能看到此帖子。", "private_from_me": "只有我的关注者才能看到此帖子。", "direct": "只有提到的用户才能看到此帖子。" + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From afa0434a02751d4e65b21c80486248fb583d7d14 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:32 +0100 Subject: [PATCH 454/733] New translations app.json (English) --- .../StringsConvertor/input/en.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 85940744c..3283645cb 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 8c20995d2c08b633aeea05f8f3b00c5e17cbe478 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:33 +0100 Subject: [PATCH 455/733] New translations app.json (Galician) --- .../StringsConvertor/input/gl.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 6d838cd06..3049e5c16 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Limpar caché", "message": "Baleirouse %s da caché correctamente." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloquear a %s", "unblock_domain": "Desbloquear a %s", "settings": "Axustes", - "delete": "Eliminar" + "delete": "Eliminar", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Inicio", @@ -168,6 +177,11 @@ "private": "Só as seguidoras poden ver a publicación.", "private_from_me": "Só as miñas seguidoras poden ver esta publicación.", "direct": "Só a usuaria mencionada pode ver a publicación." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 0a4103eb1234e1ce1db7f18a9ffcbcfffec5c72a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:35 +0100 Subject: [PATCH 456/733] New translations app.json (Portuguese, Brazilian) --- .../StringsConvertor/input/pt-BR.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 2f460619f..777111337 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Limpar Cache", "message": "%s do cache removidos com sucesso." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloquear %s", "unblock_domain": "Desbloquear %s", "settings": "Configurações", - "delete": "Excluir" + "delete": "Excluir", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Início", @@ -168,6 +177,11 @@ "private": "Somente seus seguidores podem ver essa postagem.", "private_from_me": "Somente meus seguidores podem ver essa postagem.", "direct": "Somente o usuário mencionado pode ver essa postagem." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From d79646ae36fe9e22385f2f09ba0a14ae26f2787d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:36 +0100 Subject: [PATCH 457/733] New translations app.json (Indonesian) --- .../StringsConvertor/input/id.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 1ba4ea601..377340949 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Bersihkan Cache", "message": "Berhasil menghapus %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blokir %s", "unblock_domain": "Berhenti memblokir %s", "settings": "Pengaturan", - "delete": "Hapus" + "delete": "Hapus", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Beranda", @@ -168,6 +177,11 @@ "private": "Hanya pengikut mereka yang dapat melihat postingan ini.", "private_from_me": "Hanya pengikut saya yang dapat melihat postingan ini.", "direct": "Hanya pengguna yang disebut yang dapat melihat postingan ini." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 64e6639950ab07489843e5df27fe6801f0ee0212 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:37 +0100 Subject: [PATCH 458/733] New translations app.json (Spanish, Argentina) --- .../StringsConvertor/input/es-AR.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 860d084da..054c0bffd 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Limpiar caché", "message": "Se limpió exitosamente %s de la memoria caché." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloquear a %s", "unblock_domain": "Desbloquear a %s", "settings": "Configuración", - "delete": "Eliminar" + "delete": "Eliminar", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Principal", @@ -168,6 +177,11 @@ "private": "Sólo sus seguidores pueden ver este mensaje.", "private_from_me": "Sólo mis seguidores pueden ver este mensaje.", "direct": "Sólo el usuario mencionado puede ver este mensaje." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From b1850835b4050e2a6d7b588b5dc345516be86fba Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:38 +0100 Subject: [PATCH 459/733] New translations app.json (Thai) --- .../StringsConvertor/input/th.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index ffd502057..b36536f63 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "ล้างแคช", "message": "ล้างแคช %s สำเร็จ" + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "ปิดกั้น %s", "unblock_domain": "เลิกปิดกั้น %s", "settings": "การตั้งค่า", - "delete": "ลบ" + "delete": "ลบ", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "หน้าแรก", @@ -168,6 +177,11 @@ "private": "เฉพาะผู้ติดตามของเขาเท่านั้นที่สามารถเห็นโพสต์นี้", "private_from_me": "เฉพาะผู้ติดตามของฉันเท่านั้นที่สามารถเห็นโพสต์นี้", "direct": "เฉพาะผู้ใช้ที่กล่าวถึงเท่านั้นที่สามารถเห็นโพสต์นี้" + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 562322641f616033f390c0955a8acda64c84fcc6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:39 +0100 Subject: [PATCH 460/733] New translations app.json (Latvian) --- .../StringsConvertor/input/lv.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index e65535159..1516c2048 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Bloķēt %s", "unblock_domain": "Atbloķēt %s", "settings": "Iestatījumi", - "delete": "Dzēst" + "delete": "Dzēst", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Sākums", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From f09a4eadbcf956cb3c7cd02333720cd97fa44404 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:40 +0100 Subject: [PATCH 461/733] New translations app.json (Hindi) --- .../StringsConvertor/input/hi.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 471c7b036..23fa6b545 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 2fcddabf68a42c14b953ab7748539f3d2f5b3e60 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:42 +0100 Subject: [PATCH 462/733] New translations app.json (English, United States) --- .../StringsConvertor/input/en-US.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 85940744c..3283645cb 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 368db861398fa77d68d1f82cf4f93aa76ea4abed Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:43 +0100 Subject: [PATCH 463/733] New translations app.json (Welsh) --- .../StringsConvertor/input/cy.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index df25db90d..61df7a496 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clirio storfa", "message": "Cliriwyd storfa %s yn llwyddiannus." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blocio %s", "unblock_domain": "Dadflocio %s", "settings": "Gosodiadau", - "delete": "Dileu" + "delete": "Dileu", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Hafan", @@ -168,6 +177,11 @@ "private": "Dim ond eu dilynwyr nhw sy'n gallu gweld y post hwn.", "private_from_me": "Dim ond fy nilynwyr ni sy'n gallu gweld y post hwn.", "direct": "Dim ond y ddefnyddiwr â soniwyd sy'n gallu gweld y post hwn." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 43027985335985c60ce847d52df55ae9781d05fc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:44 +0100 Subject: [PATCH 464/733] New translations app.json (Sinhala) --- .../StringsConvertor/input/si.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 7440c5e31..e92151030 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 4945d573b7ac0d78b83192392c76079289da0e13 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:45 +0100 Subject: [PATCH 465/733] New translations app.json (Kurmanji (Kurdish)) --- .../StringsConvertor/input/kmr.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index a48ff9cea..912b68a99 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Pêşbîrê pak bike", "message": "Pêşbîra %s biserketî hate pakkirin." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s asteng bike", "unblock_domain": "%s asteng neke", "settings": "Sazkarî", - "delete": "Jê bibe" + "delete": "Jê bibe", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Serrûpel", @@ -168,6 +177,11 @@ "private": "Tenê şopînerên wan dikarin vê şandiyê bibînin.", "private_from_me": "Tenê şopînerên min dikarin vê şandiyê bibînin.", "direct": "Tenê bikarhênerê qalkirî dikare vê şandiyê bibîne." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 40e6af62893dc0f723af4cbca6afaed3944b5dff Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:47 +0100 Subject: [PATCH 466/733] New translations app.json (Sorani (Kurdish)) --- .../StringsConvertor/input/ckb.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 73258f53f..165615294 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "بیرگە پاک بکەوە", "message": "سەرکەوتووانە بیرگەی %s پاک کرایەوە." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s ئاستەنگ بکە", "unblock_domain": "%s ئاستەنگ مەکە", "settings": "رێکخستنەکان", - "delete": "بیسڕەوە" + "delete": "بیسڕەوە", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "ماڵەوە", @@ -168,6 +177,11 @@ "private": "تەنیا شوێنکەوتووەکانی دەتوانن ئەم پۆستە ببینن.", "private_from_me": "تەنیا شوێنکەوتووەکانم دەتوانن ئەم پۆستە ببینن.", "direct": "تەنیا بەکارهێنەرە ئاماژە پێکراوەکە دەتوانێت ئەم پۆستە ببینێت." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 7fb73eb64d5405be97851171b45ae8fee45165d5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:48 +0100 Subject: [PATCH 467/733] New translations app.json (Icelandic) --- .../StringsConvertor/input/is.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index d9c36e449..684c44920 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Hreinsa skyndiminni", "message": "Tókst að hreinsa %s skyndiminni." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Útiloka %s", "unblock_domain": "Opna á %s", "settings": "Stillingar", - "delete": "Eyða" + "delete": "Eyða", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Heim", @@ -168,6 +177,11 @@ "private": "Einungis fylgjendur þeirra geta séð þessa færslu.", "private_from_me": "Einungis fylgjendur mínir geta séð þessa færslu.", "direct": "Einungis notendur sem minnst er á geta séð þessa færslu." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 6f26e482869cfca2769192f985698b267b4df276 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:49 +0100 Subject: [PATCH 468/733] New translations app.json (Burmese) --- .../StringsConvertor/input/my.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 8adf8459a..5dc6ab2d9 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Cache ကို ရှင်းပါ", "message": "%s cache ကို အောင်မြင်စွာ ရှင်းလင်းပြီးပါပြီ" + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "%s ကို ဘလော့လုပ်ရန်", "unblock_domain": "%s ကို ဘလော့ဖြုတ်ရန်", "settings": "ဆက်တင်များ", - "delete": "ဖျက်" + "delete": "ဖျက်", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "အိမ်", @@ -168,6 +177,11 @@ "private": "သူတို့၏ စောင့်ကြည့်သူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်", "private_from_me": "ကျွန်ုပ်၏ စောင့်ကြည့်သူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်", "direct": "ရည်ညွှန်းခံရသောအသုံးပြုသူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်" + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 6647e61310aa057a1c4bd8044447dd4cc2e19989 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:50 +0100 Subject: [PATCH 469/733] New translations app.json (Aragonese) --- .../StringsConvertor/input/an.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index c81bb7e1c..f194a58a1 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Limpiar Caché", "message": "S'ha limpiau con exito %s de caché." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "Blocar %s", "unblock_domain": "Desbloquiar %s", "settings": "Configuración", - "delete": "Borrar" + "delete": "Borrar", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Inicio", @@ -168,6 +177,11 @@ "private": "Nomás los suyos seguidores pueden veyer este mensache.", "private_from_me": "Nomás los míos seguidores pueden veyer este mensache.", "direct": "Nomás l'usuario mencionau puede veyer este mensache." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 0dc45bda20bc73c83b8844f5a5b34038804c9759 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 10:51:51 +0100 Subject: [PATCH 470/733] New translations app.json (Hebrew) --- .../StringsConvertor/input/he.lproj/app.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 48c9d7f31..e2f71da33 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -91,7 +96,11 @@ "block_domain": "חסימת %s", "unblock_domain": "הסרת חסימה מ־%s", "settings": "הגדרות", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -168,6 +177,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { From 13c54c39f17a9b96bf4798efa2808cec10d29c30 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 07:28:05 -0500 Subject: [PATCH 471/733] Fix VoiceOver trap in thread titles --- .../View/Content/DoubleTitleLabelNavigationBarTitleView.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mastodon/Scene/Share/View/Content/DoubleTitleLabelNavigationBarTitleView.swift b/Mastodon/Scene/Share/View/Content/DoubleTitleLabelNavigationBarTitleView.swift index f5ac0f8ec..52d9c9f1a 100644 --- a/Mastodon/Scene/Share/View/Content/DoubleTitleLabelNavigationBarTitleView.swift +++ b/Mastodon/Scene/Share/View/Content/DoubleTitleLabelNavigationBarTitleView.swift @@ -51,16 +51,20 @@ extension DoubleTitleLabelNavigationBarTitleView { containerView.addArrangedSubview(titleLabel) containerView.addArrangedSubview(subtitleLabel) + + isAccessibilityElement = true } func update(title: String, subtitle: String?) { titleLabel.configure(content: PlaintextMetaContent(string: title)) update(subtitle: subtitle) + accessibilityLabel = subtitle.map { "\(title), \($0)" } ?? title } func update(titleMetaContent: MetaContent, subtitle: String?) { titleLabel.configure(content: titleMetaContent) update(subtitle: subtitle) + accessibilityLabel = subtitle.map { "\(titleMetaContent.string), \($0)" } ?? titleMetaContent.string } func update(subtitle: String?) { From cd6bdead013b94371e27699d67f519c8bb23b7b5 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 07:39:05 -0500 Subject: [PATCH 472/733] DispatchQueue.main.async --- ...Provider+StatusTableViewCellDelegate.swift | 68 +++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index 0521a3486..3fa1a4256 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -195,52 +195,50 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte ) { _ in UIPasteboard.general.url = url }, + UIAction( title: L10n.Common.Controls.Actions.share, image: Asset.Arrow.squareAndArrowUp.image.withRenderingMode(.alwaysTemplate) ) { _ in - Task { - await MainActor.run { - let activityViewController = UIActivityViewController( - activityItems: [ - URLActivityItemWithMetadata(url: url) { metadata in - metadata.title = card.title - - if let image = card.imageURL { - metadata.iconProvider = ImageProvider(url: image, filter: nil).itemProvider - } + DispatchQueue.main.async { + let activityViewController = UIActivityViewController( + activityItems: [ + URLActivityItemWithMetadata(url: url) { metadata in + metadata.title = card.title + + if let image = card.imageURL { + metadata.iconProvider = ImageProvider(url: image, filter: nil).itemProvider } - ], - applicationActivities: [] - ) - self.coordinator.present( - scene: .activityViewController( - activityViewController: activityViewController, - sourceView: statusCardControl, barButtonItem: nil - ), - from: self, - transition: .activityViewControllerPresent(animated: true) - ) - } + } + ], + applicationActivities: [] + ) + self.coordinator.present( + scene: .activityViewController( + activityViewController: activityViewController, + sourceView: statusCardControl, barButtonItem: nil + ), + from: self, + transition: .activityViewControllerPresent(animated: true) + ) } }, + UIAction( title: L10n.Common.Controls.Status.Actions.shareLinkInPost, image: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) ) { _ in - Task { - await MainActor.run { - self.coordinator.present( - scene: .compose(viewModel: ComposeViewModel( - context: self.context, - authContext: self.authContext, - destination: .topLevel, - initialContent: L10n.Common.Controls.Status.linkViaUser(url.absoluteString, "@" + (statusView.viewModel.authorUsername ?? "")) - )), - from: self, - transition: .modal(animated: true) - ) - } + DispatchQueue.main.async { + self.coordinator.present( + scene: .compose(viewModel: ComposeViewModel( + context: self.context, + authContext: self.authContext, + destination: .topLevel, + initialContent: L10n.Common.Controls.Status.linkViaUser(url.absoluteString, "@" + (statusView.viewModel.authorUsername ?? "")) + )), + from: self, + transition: .modal(animated: true) + ) } } ]) From cc4df41fbb72fa5f650c118d1136acaebeff0724 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 07:39:52 -0500 Subject: [PATCH 473/733] Disable divider autoresizing mask Co-Authored-By: Marcus Kida --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index aaca1cd6c..0a175b23b 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -128,6 +128,7 @@ public final class StatusCardControl: UIControl { containerStackView.translatesAutoresizingMaskIntoConstraints = false highlightView.translatesAutoresizingMaskIntoConstraints = false showEmbedButton.translatesAutoresizingMaskIntoConstraints = false + dividerView.translatesAutoresizingMaskIntoConstraints = false containerStackView.pinToParent() highlightView.pinToParent() From dccfb4e831393f3369088d6224bd69abe67ffab2 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 07:42:10 -0500 Subject: [PATCH 474/733] Avoid division by 0 --- .../MastodonUI/Extension/UIScreen.swift | 18 ++++++++++++++++++ .../View/Content/StatusCardControl.swift | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/Extension/UIScreen.swift diff --git a/MastodonSDK/Sources/MastodonUI/Extension/UIScreen.swift b/MastodonSDK/Sources/MastodonUI/Extension/UIScreen.swift new file mode 100644 index 000000000..831f2cb32 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Extension/UIScreen.swift @@ -0,0 +1,18 @@ +// +// UIScreen.swift +// +// +// Created by Jed Fox on 2022-12-15. +// + +import UIKit + +extension UIScreen { + public var pixelSize: CGFloat { + if scale > 0 { + return 1 / scale + } + // should never happen but just in case + return 1 + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 0a175b23b..bd2485cf4 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -184,8 +184,8 @@ public final class StatusCardControl: UIControl { super.didMoveToWindow() if let window = window { - layer.borderWidth = 1 / window.screen.scale - dividerConstraint?.constant = 1 / window.screen.scale + layer.borderWidth = window.screen.pixelSize + dividerConstraint?.constant = 1 / window.screen.pixelSize } } @@ -196,7 +196,7 @@ public final class StatusCardControl: UIControl { NSLayoutConstraint.deactivate(layoutConstraints) dividerConstraint?.deactivate() - let pixelSize = 1 / (window?.screen.scale ?? 1) + let pixelSize = 1 / (window?.screen.pixelSize ?? 1) switch layout { case .large(let aspectRatio): containerStackView.alignment = .fill From 1be9dcef667370796a42e66525340eb45aa40291 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 07:43:25 -0500 Subject: [PATCH 475/733] Bump data model version --- .../CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion | 2 +- .../{CoreData 6.xcdatamodel => CoreData 7.xcdatamodel}/contents | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/{CoreData 6.xcdatamodel => CoreData 7.xcdatamodel}/contents (100%) diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion index e660b0a08..b2d4c7f6e 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreData 6.xcdatamodel + CoreData 7.xcdatamodel diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents similarity index 100% rename from MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 6.xcdatamodel/contents rename to MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents From f8556183a3e698fc135b2f143514cf70e6c45cfc Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 15 Dec 2022 08:11:51 -0500 Subject: [PATCH 476/733] Fix inverting pizelSize! --- .../Sources/MastodonUI/View/Content/StatusCardControl.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index bd2485cf4..228159d1f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -185,7 +185,7 @@ public final class StatusCardControl: UIControl { if let window = window { layer.borderWidth = window.screen.pixelSize - dividerConstraint?.constant = 1 / window.screen.pixelSize + dividerConstraint?.constant = window.screen.pixelSize } } @@ -196,7 +196,7 @@ public final class StatusCardControl: UIControl { NSLayoutConstraint.deactivate(layoutConstraints) dividerConstraint?.deactivate() - let pixelSize = 1 / (window?.screen.pixelSize ?? 1) + let pixelSize = (window?.screen.pixelSize ?? 1) switch layout { case .large(let aspectRatio): containerStackView.alignment = .fill From 5af07fc037df6c5f44defda7daa57b133e02bcef Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:24:59 +0100 Subject: [PATCH 477/733] New translations app.json (Slovenian) --- .../StringsConvertor/input/sl.lproj/app.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 3224a7d5d..a42ec90a1 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -53,9 +53,9 @@ "message": "Uspešno počiščem predpomnilnik %s." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Opomba", + "message": "Prevod je spodletel. Morda skrbnik ni omogočil prevajanja na tem strežniku ali pa strežnik teče na starejši različici Masotodona, na kateri prevajanje še ni podprto.", + "button": "V redu" } }, "controls": { @@ -98,8 +98,8 @@ "settings": "Nastavitve", "delete": "Izbriši", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Prevedi iz: %s", + "unknown_language": "Neznano" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Samo omenjeni uporabnik lahko vidi to objavo." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Prevedeno iz jezika: %s", + "unknown_language": "Neznano", + "show_original": "Pokaži izvirnik" } }, "friendship": { From cd0992d404da4186fa22bc54dd8a968d759ee20d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:00 +0100 Subject: [PATCH 478/733] New translations app.json (Chinese Traditional) --- .../StringsConvertor/input/zh-Hant.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 40a309e9a..87a97f540 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -53,8 +53,8 @@ "message": "成功清除 %s 快取。" }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "備註", + "message": "翻譯失敗。也許管理員未於此伺服器啟用翻譯功能,或此伺服器為未支援翻譯功能之舊版本 Mastodon。", "button": "OK" } }, @@ -98,8 +98,8 @@ "settings": "設定", "delete": "刪除", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "翻譯自 %s", + "unknown_language": "未知" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "只有被提及的使用者能看到此嘟文。" }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "翻譯自 %s", + "unknown_language": "未知", + "show_original": "顯示原文" } }, "friendship": { From 10ae4b94f975428959aacba29c891d0d9cf526e2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:01 +0100 Subject: [PATCH 479/733] New translations app.json (Vietnamese) --- .../StringsConvertor/input/vi.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 4befeeb18..28150b336 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -53,8 +53,8 @@ "message": "Đã xóa %s bộ nhớ đệm." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Ghi chú", + "message": "Dịch không thành công. Có thể quản trị viên chưa bật dịch trên máy chủ này hoặc máy chủ này đang chạy phiên bản cũ hơn của Mastodon chưa hỗ trợ dịch.", "button": "OK" } }, @@ -98,8 +98,8 @@ "settings": "Cài đặt", "delete": "Xóa", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Dịch từ %s", + "unknown_language": "Chưa xác định" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Chỉ người được nhắc đến có thể thấy tút." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Dịch từ %s", + "unknown_language": "Không xác định", + "show_original": "Bản gốc" } }, "friendship": { From ecbb8a5b54d57d6e6bec8b7b66839764022a459b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:02 +0100 Subject: [PATCH 480/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index ebc1d922c..1fc08181c 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -55,7 +55,7 @@ "translation_failed": { "title": "Note", "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "button": "확인" } }, "controls": { @@ -179,9 +179,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "%s에서 번역됨", + "unknown_language": "알 수 없음", + "show_original": "원본 보기" } }, "friendship": { From 4472c5c0238dcf954df5dd2b023f07df27d8b631 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:03 +0100 Subject: [PATCH 481/733] New translations app.json (Swedish) --- .../StringsConvertor/input/sv.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 68f47af4f..6470c9e23 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -53,8 +53,8 @@ "message": "Rensade %s cache." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Anteckning", + "message": "Översättningen misslyckades. Det kan hända att administratören inte har aktiverat översättningar på den här servern eller att servern kör en äldre version av Mastodon som inte har stöd för översättningar ännu.", "button": "OK" } }, @@ -98,8 +98,8 @@ "settings": "Inställningar", "delete": "Radera", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Översätt från %s", + "unknown_language": "Okänt" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Endast omnämnda användare kan se detta inlägg." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Översatt från %s", + "unknown_language": "Okänt", + "show_original": "Visa original" } }, "friendship": { From f68bb4b297fdef0ed3ff9595208cecb9e0eb8f48 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:04 +0100 Subject: [PATCH 482/733] New translations app.json (Catalan) --- .../StringsConvertor/input/ca.lproj/app.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 64791cc01..717424714 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -53,9 +53,9 @@ "message": "S'ha netejat correctament la memòria cau de %s." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Nota", + "message": "La traducció ha fallat. Potser l'administrador d'aquest servidor no ha activat les traduccions o està executant una versió vella de Mastodon on les traduccions encara no eren suportades.", + "button": "D'acord" } }, "controls": { @@ -98,8 +98,8 @@ "settings": "Configuració", "delete": "Suprimeix", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traduït del %s", + "unknown_language": "Desconegut" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Només l'usuari mencionat pot veure aquesta publicació." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Traduït des d'el %s", + "unknown_language": "Desconegut", + "show_original": "Mostra l'original" } }, "friendship": { From e8835f727f4021d1e92732caa55f6ca0737fe5b2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:06 +0100 Subject: [PATCH 483/733] New translations app.json (German) --- .../StringsConvertor/input/de.lproj/app.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index e4c5ab91b..246cf120f 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -53,8 +53,8 @@ "message": "%s erfolgreich aus dem Cache gelöscht." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Hinweis", + "message": "Übersetzung fehlgeschlagen. Möglicherweise hat der Administrator die Übersetzungen auf diesem Server nicht aktiviert oder dieser Server läuft mit einer älteren Version von Mastodon, in der Übersetzungen noch nicht unterstützt werden.", "button": "OK" } }, @@ -98,8 +98,8 @@ "settings": "Einstellungen", "delete": "Löschen", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Übersetzen von %s", + "unknown_language": "Unbekannt" } }, "tabs": { @@ -179,8 +179,8 @@ "direct": "Nur erwähnte Benutzer können diesen Beitrag sehen." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", + "translated_from": "Übersetzt von %s", + "unknown_language": "Unbekannt", "show_original": "Shown Original" } }, From 2215232f2f2b70eae9dccef7ce5f72c9318beddc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:07 +0100 Subject: [PATCH 484/733] New translations app.json (Italian) --- .../StringsConvertor/input/it.lproj/app.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index c6136b4b6..05a26e0cc 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -53,8 +53,8 @@ "message": "Cache %s pulita con successo." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Nota", + "message": "Traduzione fallita. Forse l'amministratore non ha abilitato le traduzioni su questo server o questo server sta eseguendo una versione precedente di Mastodon in cui le traduzioni non sono ancora supportate.", "button": "OK" } }, @@ -98,8 +98,8 @@ "settings": "Impostazioni", "delete": "Elimina", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traduci da %s", + "unknown_language": "Sconosciuto" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Solo l'utente menzionato può vedere questo post." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Tradotto da %s", + "unknown_language": "Sconosciuto", + "show_original": "Mostra l'originale" } }, "friendship": { From f0d4a9541e99bada8b5145e905fe598f41092107 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:08 +0100 Subject: [PATCH 485/733] New translations app.json (Spanish, Argentina) --- .../StringsConvertor/input/es-AR.lproj/app.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 054c0bffd..ef5f18c0c 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -53,9 +53,9 @@ "message": "Se limpió exitosamente %s de la memoria caché." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Nota", + "message": "Falló la traducción. Tal vez el administrador no habilitó las traducciones en este servidor, o este servidor está ejecutando una versión antigua de Mastodon en donde las traducciones aún no estaban disponibles.", + "button": "Aceptar" } }, "controls": { @@ -98,8 +98,8 @@ "settings": "Configuración", "delete": "Eliminar", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traducido desde el %s", + "unknown_language": "Desconocido" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Traducido desde el %s", + "unknown_language": "Desconocido", + "show_original": "Mostrar original" } }, "friendship": { From f4aebe7f6bac072f1450b0e10b1407ffeb556a3a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 14:25:09 +0100 Subject: [PATCH 486/733] New translations app.json (Kurmanji (Kurdish)) --- .../StringsConvertor/input/kmr.lproj/app.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 912b68a99..afe66a052 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -53,9 +53,9 @@ "message": "Pêşbîra %s biserketî hate pakkirin." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Nîşe", + "message": "Werger têk çû. Dibe ku rêvebir werger li ser vê rajakarê çalak nekiribe an jî ev rajakar guhertoyek kevntir a Mastodon e ku werger hîn nehatiye piştgirîkirin.", + "button": "BAŞ E" } }, "controls": { @@ -98,8 +98,8 @@ "settings": "Sazkarî", "delete": "Jê bibe", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Ji %s hate wergerandin", + "unknown_language": "Nenas" } }, "tabs": { @@ -179,9 +179,9 @@ "direct": "Tenê bikarhênerê qalkirî dikare vê şandiyê bibîne." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Ji %s hate wergerandin", + "unknown_language": "Nenas", + "show_original": "A resen nîşan bide" } }, "friendship": { From 12abde520771c9f71869d61870aea9dc5bb9941d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:10 +0100 Subject: [PATCH 487/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index a42ec90a1..79ec5e3d8 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Ustvari račun", "see_more": "Pokaži več", "preview": "Predogled", + "copy": "Copy", "share": "Deli", "share_user": "Deli %s", "share_post": "Deli objavo", @@ -141,6 +142,8 @@ "sensitive_content": "Občutljiva vsebina", "media_content_warning": "Tapnite kamorkoli, da razkrijete", "tap_to_reveal": "Tapnite za razkritje", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Glasuj", "closed": "Zaprto" @@ -162,6 +165,7 @@ "show_image": "Pokaži sliko", "show_gif": "Pokaži GIF", "show_video_player": "Pokaži predvajalnik", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tapnite, nato držite, da se pojavi meni" }, "tag": { From bb6f42d7f2ec1c2b4c91da3fca15fca5a516b1b6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:11 +0100 Subject: [PATCH 488/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 87a97f540..17b468fd8 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "新增帳號", "see_more": "檢視更多", "preview": "預覽", + "copy": "Copy", "share": "分享", "share_user": "分享 %s", "share_post": "分享嘟文", @@ -141,6 +142,8 @@ "sensitive_content": "敏感內容", "media_content_warning": "輕觸任何地方以顯示", "tap_to_reveal": "輕觸以顯示", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "投票", "closed": "已關閉" @@ -162,6 +165,7 @@ "show_image": "顯示圖片", "show_gif": "顯示 GIF", "show_video_player": "顯示影片播放器", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "輕觸然後按住以顯示選單" }, "tag": { From fd62873e7ebfe327f9c296793cff965effd396a5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:13 +0100 Subject: [PATCH 489/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 28150b336..2b6807f61 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Tạo tài khoản", "see_more": "Xem thêm", "preview": "Xem trước", + "copy": "Copy", "share": "Chia sẻ", "share_user": "Chia sẻ %s", "share_post": "Chia sẻ tút", @@ -141,6 +142,8 @@ "sensitive_content": "Nội dung nhạy cảm", "media_content_warning": "Nhấn để hiển thị", "tap_to_reveal": "Nhấn để xem", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Bình chọn", "closed": "Kết thúc" @@ -162,6 +165,7 @@ "show_image": "Hiển thị hình ảnh", "show_gif": "Hiển thị GIF", "show_video_player": "Hiện trình phát video", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Nhấn giữ để hiện menu" }, "tag": { From f0daaa1479db8aa225ac4862defce6393e685531 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:14 +0100 Subject: [PATCH 490/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 1fc08181c..b2b10ce63 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "계정 생성", "see_more": "더 보기", "preview": "미리보기", + "copy": "Copy", "share": "공유", "share_user": "%s를 공유", "share_post": "게시물 공유", @@ -141,6 +142,8 @@ "sensitive_content": "민감한 콘텐츠", "media_content_warning": "아무 곳이나 눌러서 보기", "tap_to_reveal": "눌러서 확인", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "투표", "closed": "마감" @@ -162,6 +165,7 @@ "show_image": "이미지 표시", "show_gif": "GIF 보기", "show_video_player": "비디오 플레이어 보기", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 2ad9a763659684a295b07493ae2329c9ec612b3e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:15 +0100 Subject: [PATCH 491/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 6470c9e23..a84936e47 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Skapa konto", "see_more": "Visa mer", "preview": "Förhandsvisa", + "copy": "Copy", "share": "Dela", "share_user": "Dela %s", "share_post": "Dela inlägg", @@ -141,6 +142,8 @@ "sensitive_content": "Känsligt innehåll", "media_content_warning": "Tryck var som helst för att visa", "tap_to_reveal": "Tryck för att visa", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Rösta", "closed": "Stängd" @@ -162,6 +165,7 @@ "show_image": "Visa bild", "show_gif": "Visa GIF", "show_video_player": "Visa videospelare", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tryck och håll ned för att visa menyn" }, "tag": { From 5e395433f584f110eef64011618ebf5b5379fb9d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:17 +0100 Subject: [PATCH 492/733] New translations app.json (French) --- Localization/StringsConvertor/input/fr.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 1815a5052..c9597cb35 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Créer un compte", "see_more": "Voir plus", "preview": "Aperçu", + "copy": "Copy", "share": "Partager", "share_user": "Partager %s", "share_post": "Partager la publication", @@ -141,6 +142,8 @@ "sensitive_content": "Contenu sensible", "media_content_warning": "Tapotez n’importe où pour révéler la publication", "tap_to_reveal": "Appuyer pour afficher", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Voter", "closed": "Fermé" @@ -162,6 +165,7 @@ "show_image": "Afficher l’image", "show_gif": "Afficher le GIF", "show_video_player": "Afficher le lecteur vidéo", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Appuyez et maintenez pour afficher le menu" }, "tag": { From b1e0c5c92b8d80428823791f84a2e936b2e410e2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:18 +0100 Subject: [PATCH 493/733] New translations app.json (Turkish) --- Localization/StringsConvertor/input/tr.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 6ea40e510..c0078755a 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Hesap oluştur", "see_more": "Daha Fazla Gör", "preview": "Önizleme", + "copy": "Copy", "share": "Paylaş", "share_user": "%s ile paylaş", "share_post": "Gönderiyi Paylaş", @@ -141,6 +142,8 @@ "sensitive_content": "Hassas İçerik", "media_content_warning": "Göstermek için herhangi bir yere basın", "tap_to_reveal": "Göstermek için basın", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Oy ver", "closed": "Kapandı" @@ -162,6 +165,7 @@ "show_image": "Görüntüyü göster", "show_gif": "GIF'i göster", "show_video_player": "Video oynatıcıyı göster", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Menüyü göstermek için dokunun ve basılı tutun" }, "tag": { From 0299661d0ca4970ab8b616c47d11c806cc672b85 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:19 +0100 Subject: [PATCH 494/733] New translations app.json (Czech) --- Localization/StringsConvertor/input/cs.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 1b63d6a44..306eabbdb 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Vytvořit účet", "see_more": "Zobrazit více", "preview": "Náhled", + "copy": "Copy", "share": "Sdílet", "share_user": "Sdílet %s", "share_post": "Sdílet příspěvek", @@ -141,6 +142,8 @@ "sensitive_content": "Citlivý obsah", "media_content_warning": "Klepnutím kdekoli zobrazíte", "tap_to_reveal": "Klepnutím zobrazit", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Hlasovat", "closed": "Uzavřeno" @@ -162,6 +165,7 @@ "show_image": "Zobrazit obrázek", "show_gif": "Zobrazit GIF", "show_video_player": "Zobrazit video přehrávač", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Klepnutím podržte pro zobrazení nabídky" }, "tag": { From 272c9ea8fea8f0bf7fb9f016e1b9d457602f7534 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:20 +0100 Subject: [PATCH 495/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index a53eb143a..56a12dadd 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Створити обліковий запис", "see_more": "Дивіться більше", "preview": "Попередній перегляд", + "copy": "Copy", "share": "Поділитись", "share_user": "Поділитися %s", "share_post": "Поділитися записом", @@ -141,6 +142,8 @@ "sensitive_content": "Контент 18+", "media_content_warning": "Натисніть будь-де, щоб показати більше", "tap_to_reveal": "Натисніть, щоб відобразити", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Проголосувати", "closed": "Зачинено" @@ -162,6 +165,7 @@ "show_image": "Показати зображення", "show_gif": "Показати GIF", "show_video_player": "Показати відеоплеєр", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Натисніть та утримуйте, щоб показати меню" }, "tag": { From 748c0caf0a6e3cf94b3e5fd41937d05e08116cd7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:21 +0100 Subject: [PATCH 496/733] New translations app.json (Romanian) --- Localization/StringsConvertor/input/ro.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index db34a1e6e..cc266098a 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 0a746d83f3d77e4d198355d0013540603a611a33 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:23 +0100 Subject: [PATCH 497/733] New translations app.json (Spanish) --- Localization/StringsConvertor/input/es.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index e8eb2572c..e13ce48b7 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "Ver más", "preview": "Vista previa", + "copy": "Copy", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir publicación", @@ -141,6 +142,8 @@ "sensitive_content": "Contenido sensible", "media_content_warning": "Pulsa en cualquier sitio para mostrar", "tap_to_reveal": "Tocar para revelar", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vota", "closed": "Cerrado" @@ -162,6 +165,7 @@ "show_image": "Mostrar imagen", "show_gif": "Mostrar GIF", "show_video_player": "Mostrar reproductor de vídeo", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Toca, después mantén para mostrar el menú" }, "tag": { From 51842290029fbca6af44f856091c2dc3deb9cd09 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:24 +0100 Subject: [PATCH 498/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index f3c034355..ce2b6f501 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "إنشاءُ حِساب", "see_more": "عرض المزيد", "preview": "مُعاينة", + "copy": "Copy", "share": "المُشارك", "share_user": "مُشارَكَةُ %s", "share_post": "مشارك المنشور", @@ -141,6 +142,8 @@ "sensitive_content": "مُحتَوى حَسَّاس", "media_content_warning": "اُنقُر لِلكَشف", "tap_to_reveal": "اُنقُر لِلكَشف", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "صَوِّت", "closed": "انتهى" @@ -162,6 +165,7 @@ "show_image": "أظْهِرِ الصُّورَة", "show_gif": "أظْهِر GIF", "show_video_player": "أظْهِر مُشَغِّلَ المَقاطِعِ المَرئِيَّة", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "اُنقُر مُطَوَّلًا لِإظْهَارِ القائِمَة" }, "tag": { From 38333b08b4a340d22ca59068b6efe456ef0a3374 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:25 +0100 Subject: [PATCH 499/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 717424714..4eeffd728 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Crea un compte", "see_more": "Mostra'n més", "preview": "Vista prèvia", + "copy": "Copia", "share": "Comparteix", "share_user": "Comparteix %s", "share_post": "Comparteix la publicació", @@ -141,6 +142,8 @@ "sensitive_content": "Contingut sensible", "media_content_warning": "Toca qualsevol lloc per a mostrar", "tap_to_reveal": "Toca per a mostrar", + "load_embed": "Carregar incrustat", + "link_via_user": "%s través de %s", "poll": { "vote": "Vota", "closed": "Finalitzada" @@ -162,6 +165,7 @@ "show_image": "Mostra la imatge", "show_gif": "Mostra el GIF", "show_video_player": "Mostra el reproductor de vídeo", + "share_link_in_post": "Compartir l'Enllaç en el Tut", "tap_then_hold_to_show_menu": "Toca i manté per a veure el menú" }, "tag": { From cd42a478aac58f5cf48c2e02db4cfadb1b7c50b5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:26 +0100 Subject: [PATCH 500/733] New translations app.json (Danish) --- Localization/StringsConvertor/input/da.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 3283645cb..3b27fd65a 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 5930f4e95c76539095849a631789a361095e1470 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:27 +0100 Subject: [PATCH 501/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 246cf120f..4d4c68bdf 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Konto erstellen", "see_more": "Mehr anzeigen", "preview": "Vorschau", + "copy": "Kopieren", "share": "Teilen", "share_user": "%s teilen", "share_post": "Beitrag teilen", @@ -141,6 +142,8 @@ "sensitive_content": "NSFW-Inhalt", "media_content_warning": "Tippe irgendwo zum Anzeigen", "tap_to_reveal": "Zum Anzeigen tippen", + "load_embed": "Eingebettetes laden", + "link_via_user": "%s via %s", "poll": { "vote": "Abstimmen", "closed": "Beendet" @@ -162,6 +165,7 @@ "show_image": "Bild anzeigen", "show_gif": "GIF anzeigen", "show_video_player": "Zeige Video-Player", + "share_link_in_post": "Link im Beitrag teilen", "tap_then_hold_to_show_menu": "Halte gedrückt um das Menü anzuzeigen" }, "tag": { From 064e5be1f6ffb0fa6f788617a926f15f8f93c442 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:28 +0100 Subject: [PATCH 502/733] New translations app.json (Basque) --- Localization/StringsConvertor/input/eu.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 9c4dc6a4b..dc8b14108 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Sortu kontua", "see_more": "Ikusi gehiago", "preview": "Aurrebista", + "copy": "Copy", "share": "Partekatu", "share_user": "Partekatu %s", "share_post": "Partekatu bidalketa", @@ -141,6 +142,8 @@ "sensitive_content": "Eduki hunkigarria", "media_content_warning": "Ukitu edonon bistaratzeko", "tap_to_reveal": "Sakatu erakusteko", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Bozkatu", "closed": "Itxita" @@ -162,6 +165,7 @@ "show_image": "Erakutsi irudia", "show_gif": "Erakutsi GIFa", "show_video_player": "Erakutsi bideo-erreproduzigailua", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Sakatu eta eutsi menua erakusteko" }, "tag": { From afa71e0c070a1ec5010ece74deec8f5df1b2902a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:29 +0100 Subject: [PATCH 503/733] New translations app.json (Finnish) --- Localization/StringsConvertor/input/fi.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 3d1ca2422..9ceb6da6d 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "Näytä lisää", "preview": "Esikatselu", + "copy": "Copy", "share": "Jaa", "share_user": "Jaa %s", "share_post": "Jaa julkaisu", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Napauta mistä tahansa paljastaaksesi", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Suljettu" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From fbd7ce11265e729ca26f9b07229beabcee142753 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:31 +0100 Subject: [PATCH 504/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 05a26e0cc..106ab151f 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Crea un account", "see_more": "Visualizza altro", "preview": "Anteprima", + "copy": "Copia", "share": "Condividi", "share_user": "Condividi %s", "share_post": "Condividi il post", @@ -141,6 +142,8 @@ "sensitive_content": "Contenuto sensibile", "media_content_warning": "Tocca ovunque per rivelare", "tap_to_reveal": "Tocca per rivelare", + "load_embed": "Carica Incorpora", + "link_via_user": "%s tramite %s", "poll": { "vote": "Vota", "closed": "Chiuso" @@ -162,6 +165,7 @@ "show_image": "Mostra immagine", "show_gif": "Mostra GIF", "show_video_player": "Mostra lettore video", + "share_link_in_post": "Condividi il collegamento nel post", "tap_then_hold_to_show_menu": "Tocca quindi tieni premuto per mostrare il menu" }, "tag": { From 4ba934fecd12119f6512c54ff4163cd10735b1c2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:31 +0100 Subject: [PATCH 505/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index d36810c9b..1b3184e9f 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "アカウント作成", "see_more": "もっと見る", "preview": "プレビュー", + "copy": "Copy", "share": "共有", "share_user": "%sを共有", "share_post": "投稿を共有", @@ -141,6 +142,8 @@ "sensitive_content": "閲覧注意", "media_content_warning": "どこかをタップして表示", "tap_to_reveal": "タップして表示", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "投票", "closed": "終了" @@ -162,6 +165,7 @@ "show_image": "画像を表示", "show_gif": "GIFを表示", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 485fdd93ff23bff1373daf7644840a15046404de Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:32 +0100 Subject: [PATCH 506/733] New translations app.json (Dutch) --- Localization/StringsConvertor/input/nl.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 9640aafb5..32a6fe3e8 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Account aanmaken", "see_more": "Meer", "preview": "Voorvertoning", + "copy": "Copy", "share": "Deel", "share_user": "Delen %s", "share_post": "Deel bericht", @@ -141,6 +142,8 @@ "sensitive_content": "Gevoelige inhoud", "media_content_warning": "Tap hier om te tonen", "tap_to_reveal": "Tik om te onthullen", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Stemmen", "closed": "Gesloten" @@ -162,6 +165,7 @@ "show_image": "Toon afbeelding", "show_gif": "GIF weergeven", "show_video_player": "Toon videospeler", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tik en houd vast om menu te tonen" }, "tag": { From 5f1d0789a80348dc226dda8793ac0d41add44189 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:34 +0100 Subject: [PATCH 507/733] New translations app.json (Portuguese) --- Localization/StringsConvertor/input/pt.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 3283645cb..3b27fd65a 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From d5e29dd69c60c4e489c4539ebfd18945e8d9be09 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:34 +0100 Subject: [PATCH 508/733] New translations app.json (Russian) --- Localization/StringsConvertor/input/ru.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 19a37db92..50931c05c 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "Ещё", "preview": "Предпросмотр", + "copy": "Copy", "share": "Поделиться", "share_user": "Поделиться %s", "share_post": "Поделиться постом", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Нажмите в любом месте, чтобы показать", "tap_to_reveal": "Нажмите, чтобы показать", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Проголосовать", "closed": "Завершён" @@ -162,6 +165,7 @@ "show_image": "Показать изображение", "show_gif": "Показать GIF", "show_video_player": "Показать видеопроигрыватель", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Нажмите и удерживайте, чтобы показать меню" }, "tag": { From 9bdbbb0841cb7ecb59a0c2a7551e8af62c7e34e6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:35 +0100 Subject: [PATCH 509/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 95da0f20f..f49311df4 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "创建账户", "see_more": "查看更多", "preview": "预览", + "copy": "Copy", "share": "分享", "share_user": "分享 %s", "share_post": "分享帖子", @@ -141,6 +142,8 @@ "sensitive_content": "敏感内容", "media_content_warning": "点击任意位置显示", "tap_to_reveal": "点击以显示", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "投票", "closed": "已关闭" @@ -162,6 +165,7 @@ "show_image": "显示图片", "show_gif": "显示 GIF", "show_video_player": "显示视频播放器", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "长按以显示菜单" }, "tag": { From b87b3555123889d8a850c44dd11b4c5de6804fae Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:36 +0100 Subject: [PATCH 510/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 3283645cb..3b27fd65a 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From e3a29b90924924fcacf6679a6cc46a4e362aca83 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:37 +0100 Subject: [PATCH 511/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 3049e5c16..f67ce57a0 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Crear conta", "see_more": "Ver máis", "preview": "Vista previa", + "copy": "Copy", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir publicación", @@ -141,6 +142,8 @@ "sensitive_content": "Contido sensible", "media_content_warning": "Toca nalgures para mostrar", "tap_to_reveal": "Toca para mostrar", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Votar", "closed": "Pechada" @@ -162,6 +165,7 @@ "show_image": "Mostrar a imaxe", "show_gif": "Mostrar GIF", "show_video_player": "Mostrar reprodutor de vídeo", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Toca e mantén preso para menú" }, "tag": { From cc7bc6e97472456308071aa7a02743c0977f019b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:38 +0100 Subject: [PATCH 512/733] New translations app.json (Portuguese, Brazilian) --- Localization/StringsConvertor/input/pt-BR.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 777111337..098304cdb 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Criar conta", "see_more": "Ver mais", "preview": "Pré-visualização", + "copy": "Copy", "share": "Compartilhar", "share_user": "Compartilhar %s", "share_post": "Compartilhar postagem", @@ -141,6 +142,8 @@ "sensitive_content": "Conteúdo sensível", "media_content_warning": "Toque em qualquer lugar para revelar", "tap_to_reveal": "Toque para revelar", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Votar", "closed": "Fechado" @@ -162,6 +165,7 @@ "show_image": "Exibir imagem", "show_gif": "Exibir GIF", "show_video_player": "Mostrar reprodutor de vídeo", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Toque e em seguida segure para exibir o menu" }, "tag": { From d14b8a1b1b8eb39ac82aaea29efb9089dd352f84 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:39 +0100 Subject: [PATCH 513/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 377340949..b6ef46040 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Buat akun", "see_more": "Lihat lebih banyak", "preview": "Pratinjau", + "copy": "Copy", "share": "Bagikan", "share_user": "Bagikan %s", "share_post": "Bagikan Postingan", @@ -141,6 +142,8 @@ "sensitive_content": "Konten Sensitif", "media_content_warning": "Ketuk di mana saja untuk melihat", "tap_to_reveal": "Ketuk untuk mengungkap", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Pilih", "closed": "Ditutup" @@ -162,6 +165,7 @@ "show_image": "Tampilkan gambar", "show_gif": "Tampilkan GIF", "show_video_player": "Tampilkan pemutar video", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Ketuk lalu tahan untuk menampilkan menu" }, "tag": { From 5d00e6d50e4276b5b2ea9db01ef820df4e0102b3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:41 +0100 Subject: [PATCH 514/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index ef5f18c0c..5cc12594c 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Crear cuenta", "see_more": "Ver más", "preview": "Previsualización", + "copy": "Copiar", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir mensaje", @@ -141,6 +142,8 @@ "sensitive_content": "Contenido sensible", "media_content_warning": "Tocá en cualquier parte para mostrar", "tap_to_reveal": "Tocá para mostrar", + "load_embed": "Cargar lo insertado", + "link_via_user": "%s vía %s", "poll": { "vote": "Votar", "closed": "Cerrada" @@ -162,6 +165,7 @@ "show_image": "Mostrar imagen", "show_gif": "Mostrar GIF", "show_video_player": "Mostrar reproductor de video", + "share_link_in_post": "Compartir enlace en mensaje", "tap_then_hold_to_show_menu": "Tocá y mantené presionado para mostrar el menú" }, "tag": { From fad1a7bab3b79a570feb8654ee202e9cfe3f231b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:42 +0100 Subject: [PATCH 515/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index b36536f63..84a73e4a1 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "สร้างบัญชี", "see_more": "ดูเพิ่มเติม", "preview": "แสดงตัวอย่าง", + "copy": "Copy", "share": "แบ่งปัน", "share_user": "แบ่งปัน %s", "share_post": "แบ่งปันโพสต์", @@ -141,6 +142,8 @@ "sensitive_content": "เนื้อหาที่ละเอียดอ่อน", "media_content_warning": "แตะที่ใดก็ตามเพื่อเปิดเผย", "tap_to_reveal": "แตะเพื่อเปิดเผย", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "ลงคะแนน", "closed": "ปิดแล้ว" @@ -162,6 +165,7 @@ "show_image": "แสดงภาพ", "show_gif": "แสดง GIF", "show_video_player": "แสดงตัวเล่นวิดีโอ", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "แตะค้างไว้เพื่อแสดงเมนู" }, "tag": { From 5954b3c03e968322263c5f08f92c69711deffe75 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:43 +0100 Subject: [PATCH 516/733] New translations app.json (Latvian) --- Localization/StringsConvertor/input/lv.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 1516c2048..6c474a628 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "Skatīt vairāk", "preview": "Priekšskatījums", + "copy": "Copy", "share": "Dalīties", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitīvs saturs", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Balsot", "closed": "Aizvērts" @@ -162,6 +165,7 @@ "show_image": "Rādīt attēlu", "show_gif": "Rādīt GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 3b08e2d041d15f903e6d81761cc992aff7b83077 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:44 +0100 Subject: [PATCH 517/733] New translations app.json (Hindi) --- Localization/StringsConvertor/input/hi.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 23fa6b545..a226a4b0c 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 147930ec48f9f3a49fd98265554cbdb230dd7f56 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:45 +0100 Subject: [PATCH 518/733] New translations app.json (English, United States) --- Localization/StringsConvertor/input/en-US.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 3283645cb..3b27fd65a 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 3b503ecd0d7640d402144cad76ce53f8d2c58bf2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:46 +0100 Subject: [PATCH 519/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 684c44920..f3015199b 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Stofna notandaaðgang", "see_more": "Sjá fleira", "preview": "Forskoða", + "copy": "Copy", "share": "Deila", "share_user": "Deila %s", "share_post": "Deila færslu", @@ -141,6 +142,8 @@ "sensitive_content": "Viðkvæmt efni", "media_content_warning": "Ýttu hvar sem er til að birta", "tap_to_reveal": "Ýttu til að birta", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Greiða atkvæði", "closed": "Lokið" @@ -162,6 +165,7 @@ "show_image": "Sýna mynd", "show_gif": "Birta GIF-myndir", "show_video_player": "Sýna myndspilara", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Ýttu og haltu til að sýna valmynd" }, "tag": { From 2113082aab3b278e2dc954ea86d2799ed65db865 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:47 +0100 Subject: [PATCH 520/733] New translations app.json (Hebrew) --- Localization/StringsConvertor/input/he.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index e2f71da33..f93b52208 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "יצירת חשבון", "see_more": "See More", "preview": "Preview", + "copy": "Copy", "share": "Share", "share_user": "Share %s", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "תוכן רגיש", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vote", "closed": "Closed" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 1fb5bccd1cbd85ded80a2e98c7807235d8776dcf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:49 +0100 Subject: [PATCH 521/733] New translations app.json (Kabyle) --- Localization/StringsConvertor/input/kab.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index ac440de6e..774755596 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Snulfu-d amiḍan", "see_more": "Wali ugar", "preview": "Taskant", + "copy": "Copy", "share": "Bḍu", "share_user": "Bḍu %s", "share_post": "Bḍu tasuffeɣt", @@ -141,6 +142,8 @@ "sensitive_content": "Agbur amḥulfu", "media_content_warning": "Sit anida tebɣiḍ i wakken ad twaliḍ", "tap_to_reveal": "Sit i uskan", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Dɣeṛ", "closed": "Ifukk" @@ -162,6 +165,7 @@ "show_image": "Sken tugna", "show_gif": "Sken GIF", "show_video_player": "Sken ameɣri n tvidyut", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Sit teǧǧeḍ aḍad-ik•im i wakken ad d-iffeɣ wumuɣ" }, "tag": { From 41ef56f83465feebdaf8293fc2bc779f4dec06f1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:50 +0100 Subject: [PATCH 522/733] New translations app.json (Scottish Gaelic) --- Localization/StringsConvertor/input/gd.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 2e3408b6c..40a1012a9 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Cruthaich cunntas", "see_more": "Seall a bharrachd", "preview": "Ro-sheall", + "copy": "Copy", "share": "Co-roinn", "share_user": "Co-roinn %s", "share_post": "Co-roinn am post", @@ -141,6 +142,8 @@ "sensitive_content": "Susbaint fhrionasach", "media_content_warning": "Thoir gnogag àite sam bith gus a nochdadh", "tap_to_reveal": "Thoir gnogag gus a nochdadh", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Cuir bhòt", "closed": "Dùinte" @@ -162,6 +165,7 @@ "show_image": "Seall an dealbh", "show_gif": "Seall an GIF", "show_video_player": "Seall cluicheadair video", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Thoir gnogag ’s cùm sìos a shealltainn a’ chlàir-thaice" }, "tag": { From 6297175470020c898f8cc0dfecfc20c5efc99eb3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:51 +0100 Subject: [PATCH 523/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 61df7a496..8b7dc902c 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Creu cyfrif", "see_more": "Gweld Mwy", "preview": "Rhagolwg", + "copy": "Copy", "share": "Rhannu", "share_user": "Rhannu %s", "share_post": "Rhannu Tŵt", @@ -141,6 +142,8 @@ "sensitive_content": "Cynnwys Sensitif", "media_content_warning": "Tapiwch unrhywle i weld", "tap_to_reveal": "Tapiwch i weld", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Pleidleisio", "closed": "Wedi cau" @@ -162,6 +165,7 @@ "show_image": "Dangos llun", "show_gif": "Dangos GIF", "show_video_player": "Dangos chwaraewr fideo", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tapiwch a gwasgu i gael y ddewislen" }, "tag": { From 97f120ae7ec045965321c41d60785ba107517ccb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:52 +0100 Subject: [PATCH 524/733] New translations app.json (Sinhala) --- Localization/StringsConvertor/input/si.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index e92151030..a2a50619a 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "තව බලන්න", "preview": "පෙරදසුන", + "copy": "Copy", "share": "බෙදාගන්න", "share_user": "%s බෙදාගන්න", "share_post": "Share Post", @@ -141,6 +142,8 @@ "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", "tap_to_reveal": "Tap to reveal", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "ඡන්දය", "closed": "වසා ඇත" @@ -162,6 +165,7 @@ "show_image": "Show image", "show_gif": "Show GIF", "show_video_player": "Show video player", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, "tag": { From 6280532c636ae83ba69dba00bbeb11c593d9d9da Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:53 +0100 Subject: [PATCH 525/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index afe66a052..e40b12687 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Ajimêr biafirîne", "see_more": "Bêtir bibîne", "preview": "Pêşdîtin", + "copy": "Copy", "share": "Parve bike", "share_user": "%s parve bike", "share_post": "Şandiyê parve bike", @@ -141,6 +142,8 @@ "sensitive_content": "Naveroka hestiyarî", "media_content_warning": "Ji bo eşkerekirinê li derekî bitikîne", "tap_to_reveal": "Ji bo dîtinê bitikîne", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Deng bide", "closed": "Girtî" @@ -162,6 +165,7 @@ "show_image": "Wêneyê nîşan bide", "show_gif": "GIF nîşan bide", "show_video_player": "Lêdera vîdyoyê nîşan bide", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Ji bo nîşandana menuyê dirêj bitikîne" }, "tag": { From cdf6883ca5c4c2df2b1059ed83a563cdfcfe14b7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:54 +0100 Subject: [PATCH 526/733] New translations app.json (Sorani (Kurdish)) --- Localization/StringsConvertor/input/ckb.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 165615294..8bf937533 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Create account", "see_more": "زیاتر ببینە", "preview": "پێشبینین", + "copy": "Copy", "share": "هاوبەشی بکە", "share_user": "%s هاوبەش بکە", "share_post": "هاوبەشی بکە", @@ -141,6 +142,8 @@ "sensitive_content": "ناوەڕۆکی هەستیار", "media_content_warning": "دەستی پیا بنێ بۆ نیشاندانی", "tap_to_reveal": "دەستی پیا بنێ بۆ نیشاندانی", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "دەنگ بدە", "closed": "داخراوە" @@ -162,6 +165,7 @@ "show_image": "وێنەکە نیشان بدە", "show_gif": "گیفەکە نیشان بدە", "show_video_player": "ڤیدیۆکە لێ بدە", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "دەستی پیا بنێ و بیگرە بۆ نیشاندانی پێڕستەکە" }, "tag": { From ea1e601f9d4ee97bf7b30a89222f4e223b92aff6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:55 +0100 Subject: [PATCH 527/733] New translations app.json (Burmese) --- Localization/StringsConvertor/input/my.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 5dc6ab2d9..c05ab2f32 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "အကောင့်ဖန်တီး", "see_more": "ပိုမိုကြည့်ရှုရန်", "preview": "အစမ်းကြည့်", + "copy": "Copy", "share": "မျှဝေ", "share_user": "%s ကို မျှဝေပါ", "share_post": "ပို့စ်ကို မျှဝေရန်", @@ -141,6 +142,8 @@ "sensitive_content": "ထိလွယ်ရှလွယ် အကြောင်းအရာ", "media_content_warning": "ဖော်ထုတ်ရန် မည်သည့်နေရာမဆို နှိပ်ပါ", "tap_to_reveal": "ဖော်ထုတ်ရန် နှိပ်ပါ", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "မဲပေး", "closed": "ပိတ်သွားပြီ" @@ -162,6 +165,7 @@ "show_image": "ဓာတ်ပုံပြရန်", "show_gif": "GIF ပြရန်", "show_video_player": "ဗီဒီယိုဖွင့်စက် ပြရန်", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "မီနူးပြရန် ဖိထားပါ" }, "tag": { From 6ec772fcee4d3145184543bd7c574dec1c81f8ff Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 15:30:57 +0100 Subject: [PATCH 528/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index f194a58a1..6f88fe606 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -83,6 +83,7 @@ "sign_up": "Crear cuenta", "see_more": "Veyer mas", "preview": "Vista previa", + "copy": "Copy", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir publicación", @@ -141,6 +142,8 @@ "sensitive_content": "Conteniu sensible", "media_content_warning": "Preta en qualsequier puesto pa amostrar", "tap_to_reveal": "Tocar pa revelar", + "load_embed": "Load Embed", + "link_via_user": "%s via %s", "poll": { "vote": "Vota", "closed": "Zarrau" @@ -162,6 +165,7 @@ "show_image": "Amostrar imachen", "show_gif": "Amostrar GIF", "show_video_player": "Amostrar reproductor de video", + "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Toca, dimpués mantiene pa amostrar lo menú" }, "tag": { From 3c8fc12659c980ab37d547a7ab386ea354ebaf9a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 16:49:46 +0100 Subject: [PATCH 529/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 4d4c68bdf..74ba8d657 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -54,7 +54,7 @@ }, "translation_failed": { "title": "Hinweis", - "message": "Übersetzung fehlgeschlagen. Möglicherweise hat der Administrator die Übersetzungen auf diesem Server nicht aktiviert oder dieser Server läuft mit einer älteren Version von Mastodon, in der Übersetzungen noch nicht unterstützt werden.", + "message": "Übersetzung fehlgeschlagen. Möglicherweise hat der/die Administrator*in die Übersetzungen auf diesem Server nicht aktiviert oder dieser Server läuft mit einer älteren Version von Mastodon, in der Übersetzungen noch nicht unterstützt wurden.", "button": "OK" } }, @@ -99,7 +99,7 @@ "settings": "Einstellungen", "delete": "Löschen", "translate_post": { - "title": "Übersetzen von %s", + "title": "Von %s übersetzen", "unknown_language": "Unbekannt" } }, @@ -185,7 +185,7 @@ "translation": { "translated_from": "Übersetzt von %s", "unknown_language": "Unbekannt", - "show_original": "Shown Original" + "show_original": "Original anzeigen" } }, "friendship": { From c039f81146b6a3de116893746bce58af3e683d37 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 16:49:47 +0100 Subject: [PATCH 530/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 84a73e4a1..3b49781a8 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -53,7 +53,7 @@ "message": "ล้างแคช %s สำเร็จ" }, "translation_failed": { - "title": "Note", + "title": "หมายเหตุ", "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", "button": "OK" } From c67f416421ab284f26a70ca32a8d407d3ce7dc4d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 18:00:55 +0100 Subject: [PATCH 531/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index a84936e47..6a2676635 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -83,7 +83,7 @@ "sign_up": "Skapa konto", "see_more": "Visa mer", "preview": "Förhandsvisa", - "copy": "Copy", + "copy": "Kopiera", "share": "Dela", "share_user": "Dela %s", "share_post": "Dela inlägg", @@ -142,7 +142,7 @@ "sensitive_content": "Känsligt innehåll", "media_content_warning": "Tryck var som helst för att visa", "tap_to_reveal": "Tryck för att visa", - "load_embed": "Load Embed", + "load_embed": "Ladda inbäddning", "link_via_user": "%s via %s", "poll": { "vote": "Rösta", @@ -165,7 +165,7 @@ "show_image": "Visa bild", "show_gif": "Visa GIF", "show_video_player": "Visa videospelare", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Dela länk i inlägg", "tap_then_hold_to_show_menu": "Tryck och håll ned för att visa menyn" }, "tag": { From 09af4f685fd7cac6fc9eb23ffdca4c329866371d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 18:00:56 +0100 Subject: [PATCH 532/733] New translations app.json (Thai) --- .../StringsConvertor/input/th.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 3b49781a8..4c17d59c3 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -54,8 +54,8 @@ }, "translation_failed": { "title": "หมายเหตุ", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "message": "การแปลล้มเหลว บางทีผู้ดูแลอาจไม่ได้เปิดใช้งานการแปลในเซิร์ฟเวอร์นี้หรือเซิร์ฟเวอร์นี้กำลังใช้ Mastodon รุ่นเก่ากว่าที่ยังไม่รองรับการแปล", + "button": "ตกลง" } }, "controls": { @@ -83,7 +83,7 @@ "sign_up": "สร้างบัญชี", "see_more": "ดูเพิ่มเติม", "preview": "แสดงตัวอย่าง", - "copy": "Copy", + "copy": "คัดลอก", "share": "แบ่งปัน", "share_user": "แบ่งปัน %s", "share_post": "แบ่งปันโพสต์", @@ -99,8 +99,8 @@ "settings": "การตั้งค่า", "delete": "ลบ", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "แปลจาก %s", + "unknown_language": "ไม่รู้จัก" } }, "tabs": { @@ -142,8 +142,8 @@ "sensitive_content": "เนื้อหาที่ละเอียดอ่อน", "media_content_warning": "แตะที่ใดก็ตามเพื่อเปิดเผย", "tap_to_reveal": "แตะเพื่อเปิดเผย", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "โหลดที่ฝังไว้", + "link_via_user": "%s ผ่าน %s", "poll": { "vote": "ลงคะแนน", "closed": "ปิดแล้ว" @@ -165,7 +165,7 @@ "show_image": "แสดงภาพ", "show_gif": "แสดง GIF", "show_video_player": "แสดงตัวเล่นวิดีโอ", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "แบ่งปันลิงก์ในโพสต์", "tap_then_hold_to_show_menu": "แตะค้างไว้เพื่อแสดงเมนู" }, "tag": { @@ -183,9 +183,9 @@ "direct": "เฉพาะผู้ใช้ที่กล่าวถึงเท่านั้นที่สามารถเห็นโพสต์นี้" }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "แปลจาก %s", + "unknown_language": "ไม่รู้จัก", + "show_original": "แสดงดั้งเดิมอยู่" } }, "friendship": { From e6f0afd05f00ee7b12af80f91532f7afdaecaafc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 19:17:01 +0100 Subject: [PATCH 533/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 2b6807f61..cf0d25a6a 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -83,7 +83,7 @@ "sign_up": "Tạo tài khoản", "see_more": "Xem thêm", "preview": "Xem trước", - "copy": "Copy", + "copy": "Chép", "share": "Chia sẻ", "share_user": "Chia sẻ %s", "share_post": "Chia sẻ tút", @@ -142,8 +142,8 @@ "sensitive_content": "Nội dung nhạy cảm", "media_content_warning": "Nhấn để hiển thị", "tap_to_reveal": "Nhấn để xem", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Nạp mã nhúng", + "link_via_user": "%s bởi %s", "poll": { "vote": "Bình chọn", "closed": "Kết thúc" @@ -165,7 +165,7 @@ "show_image": "Hiển thị hình ảnh", "show_gif": "Hiển thị GIF", "show_video_player": "Hiện trình phát video", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Chia sẻ liên kết trong Tút", "tap_then_hold_to_show_menu": "Nhấn giữ để hiện menu" }, "tag": { From 37d94fcc75760cae618417c3d74e5b09dc096636 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 20:33:27 +0100 Subject: [PATCH 534/733] New translations app.json (Chinese Traditional) --- .../StringsConvertor/input/zh-Hant.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 17b468fd8..1d26229a4 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -83,7 +83,7 @@ "sign_up": "新增帳號", "see_more": "檢視更多", "preview": "預覽", - "copy": "Copy", + "copy": "複製", "share": "分享", "share_user": "分享 %s", "share_post": "分享嘟文", @@ -142,8 +142,8 @@ "sensitive_content": "敏感內容", "media_content_warning": "輕觸任何地方以顯示", "tap_to_reveal": "輕觸以顯示", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "讀取嵌入", + "link_via_user": "%s 透過 %s", "poll": { "vote": "投票", "closed": "已關閉" @@ -165,7 +165,7 @@ "show_image": "顯示圖片", "show_gif": "顯示 GIF", "show_video_player": "顯示影片播放器", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "於嘟文中分享鏈結", "tap_then_hold_to_show_menu": "輕觸然後按住以顯示選單" }, "tag": { From 0be6cd92f754d0e9beb11d99bc71b30a27748c04 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 22:04:00 +0100 Subject: [PATCH 535/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 1d26229a4..20acba9c1 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -142,7 +142,7 @@ "sensitive_content": "敏感內容", "media_content_warning": "輕觸任何地方以顯示", "tap_to_reveal": "輕觸以顯示", - "load_embed": "讀取嵌入", + "load_embed": "讀取嵌入內容", "link_via_user": "%s 透過 %s", "poll": { "vote": "投票", From f0ad9023b44bb1de21f15929886719119526ea99 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 23:03:33 +0100 Subject: [PATCH 536/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 79ec5e3d8..37d593f60 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -83,7 +83,7 @@ "sign_up": "Ustvari račun", "see_more": "Pokaži več", "preview": "Predogled", - "copy": "Copy", + "copy": "Kopiraj", "share": "Deli", "share_user": "Deli %s", "share_post": "Deli objavo", @@ -142,8 +142,8 @@ "sensitive_content": "Občutljiva vsebina", "media_content_warning": "Tapnite kamorkoli, da razkrijete", "tap_to_reveal": "Tapnite za razkritje", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Naloži vdelano", + "link_via_user": "%s prek %s", "poll": { "vote": "Glasuj", "closed": "Zaprto" @@ -165,7 +165,7 @@ "show_image": "Pokaži sliko", "show_gif": "Pokaži GIF", "show_video_player": "Pokaži predvajalnik", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Deli povezavo v objavi", "tap_then_hold_to_show_menu": "Tapnite, nato držite, da se pojavi meni" }, "tag": { From 7bf09930c0e679ccb002a88961e9d4bf5de47e76 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 15 Dec 2022 23:03:34 +0100 Subject: [PATCH 537/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index ce2b6f501..ff3602766 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -53,9 +53,9 @@ "message": "مُحِيَ ما مَساحَتُهُ %s مِن ذاكِرَةِ التَّخزينِ المُؤقَّت بِنجاح." }, "translation_failed": { - "title": "Note", + "title": "مُلاحظة", "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "button": "حسنًا" } }, "controls": { @@ -83,7 +83,7 @@ "sign_up": "إنشاءُ حِساب", "see_more": "عرض المزيد", "preview": "مُعاينة", - "copy": "Copy", + "copy": "نَسخ", "share": "المُشارك", "share_user": "مُشارَكَةُ %s", "share_post": "مشارك المنشور", From 32fe77829412af3ddff17e04f19fe5848db13d96 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 16 Dec 2022 05:33:32 +0100 Subject: [PATCH 538/733] New translations app.json (Galician) --- .../StringsConvertor/input/gl.lproj/app.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index f67ce57a0..3f509a616 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -53,8 +53,8 @@ "message": "Baleirouse %s da caché correctamente." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Nota", + "message": "Fallou a tradución. É posible que a administración non activase a tradución neste servidor ou que o servidor teña unha versión antiga de Mastodon que non ten soporte para a tradución.", "button": "OK" } }, @@ -83,7 +83,7 @@ "sign_up": "Crear conta", "see_more": "Ver máis", "preview": "Vista previa", - "copy": "Copy", + "copy": "Copiar", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir publicación", @@ -99,8 +99,8 @@ "settings": "Axustes", "delete": "Eliminar", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traducido do %s", + "unknown_language": "Descoñecido" } }, "tabs": { @@ -142,8 +142,8 @@ "sensitive_content": "Contido sensible", "media_content_warning": "Toca nalgures para mostrar", "tap_to_reveal": "Toca para mostrar", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Cargar o contido", + "link_via_user": "%s vía %s", "poll": { "vote": "Votar", "closed": "Pechada" @@ -165,7 +165,7 @@ "show_image": "Mostrar a imaxe", "show_gif": "Mostrar GIF", "show_video_player": "Mostrar reprodutor de vídeo", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Compartir Ligazón na Publicación", "tap_then_hold_to_show_menu": "Toca e mantén preso para menú" }, "tag": { @@ -183,9 +183,9 @@ "direct": "Só a usuaria mencionada pode ver a publicación." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Traducido do %s", + "unknown_language": "Descoñecido", + "show_original": "Mostrar o orixinal" } }, "friendship": { From 89fb462754921142174bdde40585da561408beb6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 16 Dec 2022 10:19:01 +0100 Subject: [PATCH 539/733] New translations app.json (Spanish) --- .../StringsConvertor/input/es.lproj/app.json | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index e13ce48b7..6c42cc561 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -53,9 +53,9 @@ "message": "Se han limpiado con éxito %s de caché." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Nota", + "message": "Error al traducir. Tal vez el administrador no ha habilitado las traducciones en este servidor o este servidor está ejecutando una versión antigua de Mastodon donde las traducciones aún no están soportadas.", + "button": "Aceptar" } }, "controls": { @@ -79,11 +79,11 @@ "take_photo": "Tomar foto", "save_photo": "Guardar foto", "copy_photo": "Copiar foto", - "sign_in": "Log in", - "sign_up": "Create account", + "sign_in": "Iniciar sesión", + "sign_up": "Crear cuenta", "see_more": "Ver más", "preview": "Vista previa", - "copy": "Copy", + "copy": "Copiar", "share": "Compartir", "share_user": "Compartir %s", "share_post": "Compartir publicación", @@ -99,14 +99,14 @@ "settings": "Configuración", "delete": "Borrar", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traducir desde %s", + "unknown_language": "Desconocido" } }, "tabs": { "home": "Inicio", - "search_and_explore": "Search and Explore", - "notifications": "Notifications", + "search_and_explore": "Buscar y explorar", + "notifications": "Notificaciones", "profile": "Perfil" }, "keyboard": { @@ -142,17 +142,17 @@ "sensitive_content": "Contenido sensible", "media_content_warning": "Pulsa en cualquier sitio para mostrar", "tap_to_reveal": "Tocar para revelar", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Cargar incrustado", + "link_via_user": "%s vía %s", "poll": { "vote": "Vota", "closed": "Cerrado" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Enlace: %s", + "hashtag": "Etiqueta: %s", + "mention": "Mostrar Perfil: %s", + "email": "Dirección de correo electrónico: %s" }, "actions": { "reply": "Responder", @@ -165,7 +165,7 @@ "show_image": "Mostrar imagen", "show_gif": "Mostrar GIF", "show_video_player": "Mostrar reproductor de vídeo", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Compartir enlace en publicación", "tap_then_hold_to_show_menu": "Toca, después mantén para mostrar el menú" }, "tag": { @@ -183,9 +183,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Traducido de %s", + "unknown_language": "Desconocido", + "show_original": "Mostrar Original" } }, "friendship": { @@ -205,8 +205,8 @@ "unmute_user": "Desmutear a %s", "muted": "Silenciado", "edit_info": "Editar Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "show_reblogs": "Mostrar reblogs", + "hide_reblogs": "Ocultar reblogs" }, "timeline": { "filtered": "Filtrado", @@ -237,15 +237,15 @@ "log_in": "Iniciar sesión" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "Bienvenido de nuevo", + "subtitle": "Inicie sesión en el servidor en el que creó su cuenta.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Introduzca la URL o busque su servidor" } }, "server_picker": { "title": "Elige un servidor,\ncualquier servidor.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "subtitle": "Escoge un servidor basado en tu región, intereses o un propósito general. Aún puedes chatear con cualquiera en Mastodon, independientemente de tus servidores.", "button": { "category": { "all": "Todas", @@ -272,7 +272,7 @@ "category": "CATEGORÍA" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Buscar comunidades o introducir URL" }, "empty_state": { "finding_servers": "Encontrando servidores disponibles...", @@ -406,12 +406,12 @@ "attachment_broken": "Este %s está roto y no puede\nsubirse a Mastodon.", "description_photo": "Describe la foto para los usuarios con dificultad visual...", "description_video": "Describe el vídeo para los usuarios con dificultad visual...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "load_failed": "Carga fallida", + "upload_failed": "Error al cargar", + "can_not_recognize_this_media_attachment": "No se puede reconocer este archivo adjunto", + "attachment_too_large": "Adjunto demasiado grande", + "compressing_state": "Comprimiendo...", + "server_processing_state": "Procesando en el servidor..." }, "poll": { "duration_time": "Duración: %s", @@ -422,8 +422,8 @@ "three_days": "4 Días", "seven_days": "7 Días", "option_number": "Opción %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "the_poll_is_invalid": "La encuesta no es válida", + "the_poll_has_empty_option": "La encuesta tiene una opción vacía" }, "content_warning": { "placeholder": "Escribe una advertencia precisa aquí..." @@ -445,8 +445,8 @@ "enable_content_warning": "Activar Advertencia de Contenido", "disable_content_warning": "Desactivar Advertencia de Contenido", "post_visibility_menu": "Menú de Visibilidad de la Publicación", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Opciones de Publicación", + "posting_as": "Publicado como %s" }, "keyboard": { "discard_post": "Descartar Publicación", @@ -473,8 +473,8 @@ "content": "Contenido" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Verificado en %s", + "long": "La propiedad de este enlace fue verificada el %s" } }, "segmented_control": { @@ -502,12 +502,12 @@ "message": "Confirmar para desbloquear a %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Mostrar reblogs", + "message": "Confirmar para mostrar reblogs" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Ocultar reblogs", + "message": "Confirmar para ocultar reblogs" } }, "accessibility": { @@ -739,18 +739,18 @@ "accessibility_hint": "Haz doble toque para descartar este asistente" }, "bookmark": { - "title": "Bookmarks" + "title": "Marcadores" }, "followed_tags": { - "title": "Followed Tags", + "title": "Etiquetas seguidas", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "publicaciones", + "participants": "participantes", + "posts_today": "publicaciones de hoy" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Seguir", + "unfollow": "Dejar de seguir" } } } From fb6ccfa67186f009fe948db69f4a8a1a0af9d760 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 16 Dec 2022 10:19:02 +0100 Subject: [PATCH 540/733] New translations Localizable.stringsdict (Spanish) --- .../StringsConvertor/input/es.lproj/Localizable.stringsdict | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict index ca07b6b28..0a904fcfd 100644 --- a/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + Quedan %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 carácter other - %ld characters + %ld caracteres plural.count.followed_by_and_mutual From ddf6e691fe5cdcf6d8a3b2a9d9f40c2461595fcc Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 16 Dec 2022 10:28:06 +0100 Subject: [PATCH 541/733] IOS-32: Fix paragraph margins in compose --- .../Sources/MastodonUI/SwiftUI/MetaTextViewRepresentable.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/SwiftUI/MetaTextViewRepresentable.swift b/MastodonSDK/Sources/MastodonUI/SwiftUI/MetaTextViewRepresentable.swift index 8796feb06..9e4d968de 100644 --- a/MastodonSDK/Sources/MastodonUI/SwiftUI/MetaTextViewRepresentable.swift +++ b/MastodonSDK/Sources/MastodonUI/SwiftUI/MetaTextViewRepresentable.swift @@ -50,6 +50,8 @@ public struct MetaTextViewRepresentable: UIViewRepresentable { .foregroundColor: Asset.Colors.brand.color, ] + metaText.paragraphStyle = NSMutableParagraphStyle() + configurationHandler(metaText) metaText.configure(content: PlaintextMetaContent(string: string)) From 54d0b06d8daadbd0db915d1d2d1f878e275ae91e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 16 Dec 2022 13:05:38 +0100 Subject: [PATCH 542/733] New translations Localizable.stringsdict (Swedish) --- .../input/sv.lproj/Localizable.stringsdict | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict index 3cbfeae6d..20f5213e9 100644 --- a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict @@ -280,7 +280,7 @@ NSStringFormatValueTypeKey ld one - %ld år kvar + 1 år kvar other %ld år kvar @@ -296,7 +296,7 @@ NSStringFormatValueTypeKey ld one - %ld månad kvar + 1 månad kvar other %ld månader kvar @@ -360,7 +360,7 @@ NSStringFormatValueTypeKey ld one - %ld sekund kvar + 1 sekund kvar other %ld sekunder kvar @@ -408,7 +408,7 @@ NSStringFormatValueTypeKey ld one - %ldd sedan + 1d sedan other %ldd sedan From 2e6d9841e73d3fd084297d434dcffddd42a59e33 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 16 Dec 2022 14:03:39 +0100 Subject: [PATCH 543/733] New translations Localizable.stringsdict (Swedish) --- .../StringsConvertor/input/sv.lproj/Localizable.stringsdict | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict index 20f5213e9..43a0ff8e4 100644 --- a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict @@ -312,7 +312,7 @@ NSStringFormatValueTypeKey ld one - %ld dag kvar + 1 dag kvar other %ld dagar kvar @@ -424,7 +424,7 @@ NSStringFormatValueTypeKey ld one - %ldt sedan + 1t sedan other %ldt sedan From eb5707ef55e7fd454d02cc9a2af2f927f833f941 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 16 Dec 2022 17:51:01 +0100 Subject: [PATCH 544/733] Bump version --- Mastodon.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0f86c9294..600d92258 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -3916,7 +3916,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.8; + MARKETING_VERSION = 1.4.9; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3945,7 +3945,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.8; + MARKETING_VERSION = 1.4.9; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4118,7 +4118,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.8; + MARKETING_VERSION = 1.4.9; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4401,7 +4401,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.8; + MARKETING_VERSION = 1.4.9; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From 1d7dc2f2667fda4ed4ba2cf882e61f1ccdcf5739 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 17 Dec 2022 20:26:20 +0100 Subject: [PATCH 545/733] Bump to iOS 15 deployment target and fix build issues --- Mastodon.xcodeproj/project.pbxproj | 8 ++-- Mastodon/Diffable/Status/StatusSection.swift | 6 +-- .../UICollectionViewDiffableDataSource.swift | 18 +------- .../UITableViewDiffableDataSource.swift | 19 +-------- .../HomeTimelineViewModel+Diffable.swift | 8 +--- .../HomeTimeline/HomeTimelineViewModel.swift | 16 ++------ ...tificationTimelineViewModel+Diffable.swift | 8 +--- .../MastodonPickServerViewController.swift | 6 +-- .../Register/MastodonRegisterView.swift | 17 ++------ .../MastodonServerRulesViewController.swift | 6 +-- .../OnboardingViewControllerAppearance.swift | 6 +-- .../Welcome/WelcomeViewController.swift | 6 +-- .../FollowerListViewModel+Diffable.swift | 7 +--- .../FollowingListViewModel+Diffable.swift | 9 +--- .../UserLIst/UserListViewModel+Diffable.swift | 9 +--- .../ReportStatusViewController.swift | 6 +-- .../ReportSupplementaryViewController.swift | 6 +-- .../ReportViewControllerAppearance.swift | 6 +-- .../Search/Search/SearchViewController.swift | 5 +-- .../SearchHistoryViewModel+Diffable.swift | 2 +- .../SuggestionAccountViewModel+Diffable.swift | 15 +------ .../Thread/ThreadViewModel+Diffable.swift | 8 +--- MastodonSDK/Package.swift | 2 +- .../Extension/NSManagedObjectContext.swift | 41 ++++--------------- .../Service/Theme/ThemeService.swift | 10 +---- .../Sources/MastodonUI/Extension/Date.swift | 10 ++--- .../Vendor/MetaTextView+PasteExtensions.swift | 22 +++++----- .../View/Content/StatusCardControl.swift | 29 +++++-------- .../View/Content/StatusView+ViewModel.swift | 7 +--- .../MastodonUI/View/Content/StatusView.swift | 7 +--- MastodonTests/MastodonTests.swift | 1 - Podfile | 2 +- 32 files changed, 74 insertions(+), 254 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 600d92258..b708de0a9 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -3831,7 +3831,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INTENTS_CODEGEN_LANGUAGE = Swift; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -3889,7 +3889,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INTENTS_CODEGEN_LANGUAGE = Swift; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -4091,7 +4091,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INTENTS_CODEGEN_LANGUAGE = Swift; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -4373,7 +4373,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INTENTS_CODEGEN_LANGUAGE = Swift; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; diff --git a/Mastodon/Diffable/Status/StatusSection.swift b/Mastodon/Diffable/Status/StatusSection.swift index 8ccb32c0c..49591b86d 100644 --- a/Mastodon/Diffable/Status/StatusSection.swift +++ b/Mastodon/Diffable/Status/StatusSection.swift @@ -228,11 +228,7 @@ extension StatusSection { } var _snapshot = NSDiffableDataSourceSnapshot() _snapshot.appendSections([.main]) - if #available(iOS 15.0, *) { - statusView.pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(_snapshot) - } else { - statusView.pollTableViewDiffableDataSource?.apply(_snapshot, animatingDifferences: false) - } + statusView.pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(_snapshot) } } diff --git a/Mastodon/Extension/UICollectionViewDiffableDataSource.swift b/Mastodon/Extension/UICollectionViewDiffableDataSource.swift index 07d2fbd12..d7a8affda 100644 --- a/Mastodon/Extension/UICollectionViewDiffableDataSource.swift +++ b/Mastodon/Extension/UICollectionViewDiffableDataSource.swift @@ -13,11 +13,7 @@ extension UICollectionViewDiffableDataSource { snapshot: NSDiffableDataSourceSnapshot, completion: (() -> Void)? = nil ) { - if #available(iOS 15.0, *) { - self.applySnapshotUsingReloadData(snapshot, completion: completion) - } else { - self.apply(snapshot, animatingDifferences: false, completion: completion) - } + self.applySnapshotUsingReloadData(snapshot, completion: completion) } func applySnapshot( @@ -25,16 +21,6 @@ extension UICollectionViewDiffableDataSource { animated: Bool, completion: (() -> Void)? = nil) { - if #available(iOS 15.0, *) { - self.apply(snapshot, animatingDifferences: animated, completion: completion) - } else { - if animated { - self.apply(snapshot, animatingDifferences: true, completion: completion) - } else { - UIView.performWithoutAnimation { - self.apply(snapshot, animatingDifferences: true, completion: completion) - } - } - } + self.apply(snapshot, animatingDifferences: animated, completion: completion) } } diff --git a/Mastodon/Extension/UITableViewDiffableDataSource.swift b/Mastodon/Extension/UITableViewDiffableDataSource.swift index 5006417a4..6e3968a14 100644 --- a/Mastodon/Extension/UITableViewDiffableDataSource.swift +++ b/Mastodon/Extension/UITableViewDiffableDataSource.swift @@ -13,28 +13,13 @@ extension UITableViewDiffableDataSource { snapshot: NSDiffableDataSourceSnapshot, completion: (() -> Void)? = nil ) { - if #available(iOS 15.0, *) { - self.applySnapshotUsingReloadData(snapshot, completion: completion) - } else { - self.apply(snapshot, animatingDifferences: false, completion: completion) - } + self.applySnapshotUsingReloadData(snapshot, completion: completion) } func applySnapshot( _ snapshot: NSDiffableDataSourceSnapshot, animated: Bool, completion: (() -> Void)? = nil) { - - if #available(iOS 15.0, *) { - self.apply(snapshot, animatingDifferences: animated, completion: completion) - } else { - if animated { - self.apply(snapshot, animatingDifferences: true, completion: completion) - } else { - UIView.performWithoutAnimation { - self.apply(snapshot, animatingDifferences: true, completion: completion) - } - } - } + self.apply(snapshot, animatingDifferences: animated, completion: completion) } } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index ff3224d3d..3d59b3403 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -131,17 +131,13 @@ extension HomeTimelineViewModel { snapshot: NSDiffableDataSourceSnapshot, animatingDifferences: Bool ) async { - diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) + await diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) } @MainActor func updateSnapshotUsingReloadData( snapshot: NSDiffableDataSourceSnapshot ) { - if #available(iOS 15.0, *) { - self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) - } else { - diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil) - } + self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) } struct Difference { diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index edd431e52..f0ce58597 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -149,12 +149,7 @@ extension HomeTimelineViewModel { } // reconfigure item - if #available(iOS 15.0, *) { - snapshot.reconfigureItems([item]) - } else { - // Fallback on earlier versions - snapshot.reloadItems([item]) - } + snapshot.reconfigureItems([item]) await updateSnapshotUsingReloadData(snapshot: snapshot) // fetch data @@ -177,15 +172,10 @@ extension HomeTimelineViewModel { } // reconfigure item again - if #available(iOS 15.0, *) { - snapshot.reconfigureItems([item]) - } else { - // Fallback on earlier versions - snapshot.reloadItems([item]) - } + snapshot.reconfigureItems([item]) await updateSnapshotUsingReloadData(snapshot: snapshot) } - + } // MARK: - SuggestionAccountViewModelDelegate diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift index cb623ff15..0331f401e 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift @@ -111,17 +111,13 @@ extension NotificationTimelineViewModel { snapshot: NSDiffableDataSourceSnapshot, animatingDifferences: Bool ) async { - diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) + await diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) } @MainActor func updateSnapshotUsingReloadData( snapshot: NSDiffableDataSourceSnapshot ) async { - if #available(iOS 15.0, *) { - await self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) - } else { - diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil) - } + await self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) } } diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift index 7e832ddca..057c742c1 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift @@ -43,11 +43,7 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency tableView.separatorStyle = .none tableView.backgroundColor = .clear tableView.keyboardDismissMode = .onDrag - if #available(iOS 15.0, *) { - tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude - } else { - // Fallback on earlier versions - } + tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude return tableView }() diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift index 4f28353b0..e5ca2798a 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift @@ -55,19 +55,10 @@ struct MastodonRegisterView: View { // Delete if viewModel.avatarImage != nil { Divider() - if #available(iOS 15.0, *) { - Button(role: .destructive) { - viewModel.avatarMediaMenuActionPublisher.send(.delete) - } label: { - Label(L10n.Scene.Register.Input.Avatar.delete, systemImage: "delete.left") - } - } else { - // Fallback on earlier ve rsions - Button { - viewModel.avatarMediaMenuActionPublisher.send(.delete) - } label: { - Label(L10n.Scene.Register.Input.Avatar.delete, systemImage: "delete.left") - } + Button(role: .destructive) { + viewModel.avatarMediaMenuActionPublisher.send(.delete) + } label: { + Label(L10n.Scene.Register.Input.Avatar.delete, systemImage: "delete.left") } } } label: { diff --git a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift index ea0b58e28..f850991f2 100644 --- a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift +++ b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewController.swift @@ -37,11 +37,7 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency tableView.separatorStyle = .none tableView.backgroundColor = .clear tableView.keyboardDismissMode = .onDrag - if #available(iOS 15.0, *) { - tableView.sectionHeaderTopPadding = 0 - } else { - // Fallback on earlier versions - } + tableView.sectionHeaderTopPadding = 0 return tableView }() diff --git a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift index ee01b99e8..89d77435d 100644 --- a/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift +++ b/Mastodon/Scene/Onboarding/Share/OnboardingViewControllerAppearance.swift @@ -66,11 +66,7 @@ extension OnboardingViewControllerAppearance { navigationItem.standardAppearance = barAppearance navigationItem.compactAppearance = barAppearance navigationItem.scrollEdgeAppearance = barAppearance - if #available(iOS 15.0, *) { - navigationItem.compactScrollEdgeAppearance = barAppearance - } else { - // Fallback on earlier versions - } + navigationItem.compactScrollEdgeAppearance = barAppearance } func setupNavigationBarBackgroundView() { diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 241b1eacc..b0d2f3c71 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -336,11 +336,7 @@ extension WelcomeViewController: OnboardingViewControllerAppearance { navigationItem.standardAppearance = barAppearance navigationItem.compactAppearance = barAppearance navigationItem.scrollEdgeAppearance = barAppearance - if #available(iOS 15.0, *) { - navigationItem.compactScrollEdgeAppearance = barAppearance - } else { - // Fallback on earlier versions - } + navigationItem.compactScrollEdgeAppearance = barAppearance } } diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift index 7a30c3234..199879c83 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift @@ -27,12 +27,7 @@ extension FollowerListViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems([.bottomLoader], toSection: .main) - if #available(iOS 15.0, *) { - diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil) - } else { - // Fallback on earlier versions - diffableDataSource?.apply(snapshot, animatingDifferences: false) - } + diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil) userFetchedResultsController.$records .receive(on: DispatchQueue.main) diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift b/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift index e022c5736..f139a3b79 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift @@ -28,13 +28,8 @@ extension FollowingListViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems([.bottomLoader], toSection: .main) - if #available(iOS 15.0, *) { - diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil) - } else { - // Fallback on earlier versions - diffableDataSource?.apply(snapshot, animatingDifferences: false) - } - + diffableDataSource?.applySnapshotUsingReloadData(snapshot) + userFetchedResultsController.$records .receive(on: DispatchQueue.main) .sink { [weak self] records in diff --git a/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift index acd225f0c..e843dd005 100644 --- a/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift @@ -28,13 +28,8 @@ extension UserListViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems([.bottomLoader], toSection: .main) - if #available(iOS 15.0, *) { - diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil) - } else { - // Fallback on earlier versions - diffableDataSource?.apply(snapshot, animatingDifferences: false) - } - + diffableDataSource?.applySnapshotUsingReloadData(snapshot) + // trigger initial loading stateMachine.enter(UserListViewModel.State.Reloading.self) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index 10e1ec3cd..3385a12ef 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -47,11 +47,7 @@ class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewC tableView.backgroundColor = .clear tableView.keyboardDismissMode = .onDrag tableView.allowsMultipleSelection = true - if #available(iOS 15.0, *) { - tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude - } else { - // Fallback on earlier versions - } + tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude return tableView }() diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift index 76f312273..a84a3a650 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift @@ -52,11 +52,7 @@ final class ReportSupplementaryViewController: UIViewController, NeedsDependency tableView.separatorStyle = .none tableView.backgroundColor = .clear tableView.keyboardDismissMode = .onDrag - if #available(iOS 15.0, *) { - tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude - } else { - // Fallback on earlier versions - } + tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude return tableView }() diff --git a/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift b/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift index fb9bcd63f..34d59a437 100644 --- a/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift +++ b/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift @@ -42,11 +42,7 @@ extension ReportViewControllerAppearance { navigationItem.standardAppearance = barAppearance navigationItem.compactAppearance = barAppearance navigationItem.scrollEdgeAppearance = barAppearance - if #available(iOS 15.0, *) { - navigationItem.compactScrollEdgeAppearance = barAppearance - } else { - // Fallback on earlier versions - } + navigationItem.compactScrollEdgeAppearance = barAppearance } func setupNavigationBarBackgroundView() { diff --git a/Mastodon/Scene/Search/Search/SearchViewController.swift b/Mastodon/Scene/Search/Search/SearchViewController.swift index c190a1a4c..e1505121d 100644 --- a/Mastodon/Scene/Search/Search/SearchViewController.swift +++ b/Mastodon/Scene/Search/Search/SearchViewController.swift @@ -135,10 +135,7 @@ extension SearchViewController { navigationItem.standardAppearance = navigationBarAppearance navigationItem.scrollEdgeAppearance = navigationBarAppearance navigationItem.compactAppearance = navigationBarAppearance - - if #available(iOS 15, *) { - navigationItem.compactScrollEdgeAppearance = navigationBarAppearance - } + navigationItem.compactScrollEdgeAppearance = navigationBarAppearance } private func setupSearchBar() { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift index c559523a7..201fa10d2 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift @@ -54,7 +54,7 @@ extension SearchHistoryViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems(items, toSection: .main) - diffableDataSource.apply(snapshot, animatingDifferences: false) + await diffableDataSource.apply(snapshot, animatingDifferences: false) } catch { // do nothing } diff --git a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift index 35ba305bc..afb3eb7ec 100644 --- a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift +++ b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift @@ -34,12 +34,7 @@ extension SuggestionAccountViewModel { let items: [RecommendAccountItem] = records.map { RecommendAccountItem.account($0) } snapshot.appendItems(items, toSection: .main) - if #available(iOS 15.0, *) { - tableViewDiffableDataSource.applySnapshotUsingReloadData(snapshot, completion: nil) - } else { - // Fallback on earlier versions - tableViewDiffableDataSource.applySnapshot(snapshot, animated: false, completion: nil) - } + tableViewDiffableDataSource.applySnapshotUsingReloadData(snapshot, completion: nil) } .store(in: &disposeBag) } @@ -71,13 +66,7 @@ extension SuggestionAccountViewModel { } snapshot.appendItems(items, toSection: .main) - - if #available(iOS 15.0, *) { - collectionViewDiffableDataSource.applySnapshotUsingReloadData(snapshot, completion: nil) - } else { - // Fallback on earlier versions - collectionViewDiffableDataSource.applySnapshot(snapshot, animated: false, completion: nil) - } + collectionViewDiffableDataSource.applySnapshotUsingReloadData(snapshot, completion: nil) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift index 8846c8b95..850c6bab2 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift @@ -154,17 +154,13 @@ extension ThreadViewModel { snapshot: NSDiffableDataSourceSnapshot, animatingDifferences: Bool ) async { - diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) + await diffableDataSource?.apply(snapshot, animatingDifferences: animatingDifferences) } @MainActor func updateSnapshotUsingReloadData( snapshot: NSDiffableDataSourceSnapshot ) async { - if #available(iOS 15.0, *) { - await self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) - } else { - diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil) - } + await self.diffableDataSource?.applySnapshotUsingReloadData(snapshot) } // Some UI tweaks to present replies and conversation smoothly diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 1ac22e6a7..02bde117b 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -7,7 +7,7 @@ let package = Package( name: "MastodonSDK", defaultLocalization: "en", platforms: [ - .iOS(.v14), + .iOS(.v15), ], products: [ .library( diff --git a/MastodonSDK/Sources/CoreDataStack/Extension/NSManagedObjectContext.swift b/MastodonSDK/Sources/CoreDataStack/Extension/NSManagedObjectContext.swift index b921de819..3b4818992 100644 --- a/MastodonSDK/Sources/CoreDataStack/Extension/NSManagedObjectContext.swift +++ b/MastodonSDK/Sources/CoreDataStack/Extension/NSManagedObjectContext.swift @@ -50,43 +50,16 @@ extension NSManagedObjectContext { extension NSManagedObjectContext { public func perform(block: @escaping () throws -> T) async throws -> T { - if #available(iOS 15.0, *) { - return try await perform(schedule: .enqueued) { - try block() - } - } else { - return try await withCheckedThrowingContinuation { continuation in - self.perform { - do { - let value = try block() - continuation.resume(returning: value) - } catch { - continuation.resume(throwing: error) - } - } - } // end return + return try await perform(schedule: .enqueued) { + try block() } } - + public func performChanges(block: @escaping () throws -> T) async throws -> T { - if #available(iOS 15.0, *) { - return try await perform(schedule: .enqueued) { - let value = try block() - try self.saveOrRollback() - return value - } - } else { - return try await withCheckedThrowingContinuation { continuation in - self.perform { - do { - let value = try block() - try self.saveOrRollback() - continuation.resume(returning: value) - } catch { - continuation.resume(throwing: error) - } - } - } // end return + return try await perform(schedule: .enqueued) { + let value = try block() + try self.saveOrRollback() + return value } } // end func } diff --git a/MastodonSDK/Sources/MastodonCore/Service/Theme/ThemeService.swift b/MastodonSDK/Sources/MastodonCore/Service/Theme/ThemeService.swift index 869e6875f..446fb5b63 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/Theme/ThemeService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/Theme/ThemeService.swift @@ -52,9 +52,7 @@ extension ThemeService { UINavigationBar.appearance().standardAppearance = appearance UINavigationBar.appearance().compactAppearance = appearance UINavigationBar.appearance().scrollEdgeAppearance = appearance - if #available(iOS 15.0, *) { - UINavigationBar.appearance().compactScrollEdgeAppearance = appearance - } + UINavigationBar.appearance().compactScrollEdgeAppearance = appearance // set tab bar appearance let tabBarAppearance = UITabBarAppearance() @@ -76,11 +74,7 @@ extension ThemeService { tabBarAppearance.backgroundColor = theme.tabBarBackgroundColor tabBarAppearance.selectionIndicatorTintColor = ThemeService.tintColor UITabBar.appearance().standardAppearance = tabBarAppearance - if #available(iOS 15.0, *) { - UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance - } else { - // Fallback on earlier versions - } + UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance UITabBar.appearance().barTintColor = theme.tabBarBackgroundColor // set table view cell appearance diff --git a/MastodonSDK/Sources/MastodonUI/Extension/Date.swift b/MastodonSDK/Sources/MastodonUI/Extension/Date.swift index 549dd550b..2b0cb9098 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/Date.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/Date.swift @@ -48,14 +48,10 @@ extension Date { if earlierDate.timeIntervalSince(latestDate) < -(7 * 24 * 60 * 60) { let currentYear = Date.calendar.dateComponents([.year], from: Date()) let earlierDateYear = Date.calendar.dateComponents([.year], from: earlierDate) - if #available(iOS 15.0, *) { - if currentYear.year! > earlierDateYear.year! { - return earlierDate.formatted(.dateTime.year().month(.abbreviated).day()) - } else { - return earlierDate.formatted(.dateTime.month(.abbreviated).day()) - } + if currentYear.year! > earlierDateYear.year! { + return earlierDate.formatted(.dateTime.year().month(.abbreviated).day()) } else { - return Date.abbreviatedDateFormatter.string(from: earlierDate) + return earlierDate.formatted(.dateTime.month(.abbreviated).day()) } } else { return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate) diff --git a/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift b/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift index 12e6632a7..f3fa8e0e4 100644 --- a/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift +++ b/MastodonSDK/Sources/MastodonUI/Vendor/MetaTextView+PasteExtensions.swift @@ -15,19 +15,17 @@ extension MetaTextView { // fix #660 // https://github.com/mastodon/mastodon-ios/issues/660 - if #available(iOS 15.0, *) { - var nextResponder = self.next; - - // Force the event to bubble through ALL responders - // This is a workaround as somewhere down the chain the paste event gets eaten - while (nextResponder != nil) { - if let nextResponder = nextResponder { - if (nextResponder.responds(to: #selector(UIResponderStandardEditActions.paste(_:)))) { - nextResponder.perform(#selector(UIResponderStandardEditActions.paste(_:)), with: sender) - } + var nextResponder = self.next; + + // Force the event to bubble through ALL responders + // This is a workaround as somewhere down the chain the paste event gets eaten + while (nextResponder != nil) { + if let nextResponder = nextResponder { + if (nextResponder.responds(to: #selector(UIResponderStandardEditActions.paste(_:)))) { + nextResponder.perform(#selector(UIResponderStandardEditActions.paste(_:)), with: sender) } - nextResponder = nextResponder?.next; } - } // end if + nextResponder = nextResponder?.next; + } } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift index 228159d1f..530ceea20 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusCardControl.swift @@ -33,21 +33,15 @@ public final class StatusCardControl: UIControl { private let titleLabel = UILabel() private let linkLabel = UILabel() private lazy var showEmbedButton: UIButton = { - if #available(iOS 15.0, *) { - var configuration = UIButton.Configuration.gray() - configuration.background.visualEffect = UIBlurEffect(style: .systemUltraThinMaterial) - configuration.baseBackgroundColor = .clear - configuration.cornerStyle = .capsule - configuration.buttonSize = .large - configuration.title = L10n.Common.Controls.Status.loadEmbed - configuration.image = UIImage(systemName: "play.fill") - configuration.imagePadding = 12 - return UIButton(configuration: configuration, primaryAction: UIAction { [weak self] _ in - self?.showWebView() - }) - } - - return UIButton(type: .system, primaryAction: UIAction { [weak self] _ in + var configuration = UIButton.Configuration.gray() + configuration.background.visualEffect = UIBlurEffect(style: .systemUltraThinMaterial) + configuration.baseBackgroundColor = .clear + configuration.cornerStyle = .capsule + configuration.buttonSize = .large + configuration.title = L10n.Common.Controls.Status.loadEmbed + configuration.image = UIImage(systemName: "play.fill") + configuration.imagePadding = 12 + return UIButton(configuration: configuration, primaryAction: UIAction { [weak self] _ in self?.showWebView() }) }() @@ -85,10 +79,7 @@ public final class StatusCardControl: UIControl { layer.cornerCurve = .continuous layer.cornerRadius = 10 - if #available(iOS 15, *) { - maximumContentSizeCategory = .accessibilityLarge - } - + maximumContentSizeCategory = .accessibilityLarge highlightView.backgroundColor = UIColor.label.withAlphaComponent(0.1) highlightView.isHidden = true diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 5ce4d6ec4..17fa703de 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -419,12 +419,7 @@ extension StatusView.ViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems(items, toSection: .main) - if #available(iOS 15.0, *) { - statusView.pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(snapshot) - } else { - // Fallback on earlier versions - statusView.pollTableViewDiffableDataSource?.apply(snapshot, animatingDifferences: false) - } + statusView.pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(snapshot) statusView.pollTableViewHeightLayoutConstraint.constant = CGFloat(items.count) * PollOptionTableViewCell.height statusView.setPollDisplay() diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index e73d00342..53f01cea2 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -252,12 +252,7 @@ public final class StatusView: UIView { authorView.avatarButton.avatarImageView.cancelTask() if var snapshot = pollTableViewDiffableDataSource?.snapshot() { snapshot.deleteAllItems() - if #available(iOS 15.0, *) { - pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(snapshot) - } else { - // Fallback on earlier versions - pollTableViewDiffableDataSource?.apply(snapshot, animatingDifferences: false) - } + pollTableViewDiffableDataSource?.applySnapshotUsingReloadData(snapshot) } setHeaderDisplay(isDisplay: false) diff --git a/MastodonTests/MastodonTests.swift b/MastodonTests/MastodonTests.swift index ec572fd92..91d2318da 100644 --- a/MastodonTests/MastodonTests.swift +++ b/MastodonTests/MastodonTests.swift @@ -46,7 +46,6 @@ extension MastodonTests { wait(for: [expectation], timeout: 10) } - @available(iOS 15.0, *) func testConnectOnion() async throws { let request = URLRequest( url: URL(string: "http://a232ncr7jexk2chvubaq2v6qdizbocllqap7mnn7w7vrdutyvu32jeyd.onion/@k0gen")!, diff --git a/Podfile b/Podfile index 4df2d4d7c..234713a6d 100644 --- a/Podfile +++ b/Podfile @@ -1,5 +1,5 @@ source 'https://cdn.cocoapods.org/' -platform :ios, '14.0' +platform :ios, '15.0' target 'Mastodon' do # Comment the next line if you don't want to use dynamic frameworks From af2cf75c565d0bfbb545aaa169aee67c591e4334 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 17 Dec 2022 21:46:11 +0100 Subject: [PATCH 546/733] Remove workaround for collection-views --- Mastodon.xcodeproj/project.pbxproj | 4 --- .../UICollectionViewDiffableDataSource.swift | 26 ------------------- ...MastodonPickServerViewModel+Diffable.swift | 2 +- 3 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 Mastodon/Extension/UICollectionViewDiffableDataSource.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index b708de0a9..08fdba14b 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -307,7 +307,6 @@ DB72602725E36A6F00235243 /* MastodonServerRulesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */; }; DB7274F4273BB9B200577D95 /* ListBatchFetchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7274F3273BB9B200577D95 /* ListBatchFetchViewModel.swift */; }; DB73B490261F030A002E9E9F /* SafariActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73B48F261F030A002E9E9F /* SafariActivity.swift */; }; - DB73BF4927140BA300781945 /* UICollectionViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */; }; DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */; }; DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */; }; DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */; }; @@ -881,7 +880,6 @@ DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonServerRulesViewModel.swift; sourceTree = ""; }; DB7274F3273BB9B200577D95 /* ListBatchFetchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListBatchFetchViewModel.swift; sourceTree = ""; }; DB73B48F261F030A002E9E9F /* SafariActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariActivity.swift; sourceTree = ""; }; - DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewDiffableDataSource.swift; sourceTree = ""; }; DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewDiffableDataSource.swift; sourceTree = ""; }; DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScheduler.swift; sourceTree = ""; }; DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; @@ -2285,7 +2283,6 @@ DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */, 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */, DBCC3B2F261440A50045B23D /* UITabBarController.swift */, - DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */, DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */, 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */, ); @@ -3320,7 +3317,6 @@ 2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */, DBF9814C265E339500E4BA07 /* ProfileFieldAddEntryCollectionViewCell.swift in Sources */, DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */, - DB73BF4927140BA300781945 /* UICollectionViewDiffableDataSource.swift in Sources */, DBA5E7AB263BD3F5004598BB /* TimelineTableViewCellContextMenuConfiguration.swift in Sources */, DB73B490261F030A002E9E9F /* SafariActivity.swift in Sources */, 2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */, diff --git a/Mastodon/Extension/UICollectionViewDiffableDataSource.swift b/Mastodon/Extension/UICollectionViewDiffableDataSource.swift deleted file mode 100644 index d7a8affda..000000000 --- a/Mastodon/Extension/UICollectionViewDiffableDataSource.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// UICollectionViewDiffableDataSource.swift -// Mastodon -// -// Created by Cirno MainasuK on 2021-10-11. -// - -import UIKit - -// ref: https://www.jessesquires.com/blog/2021/07/08/diffable-data-source-behavior-changes-and-reconfiguring-cells-in-ios-15/ -extension UICollectionViewDiffableDataSource { - func reloadData( - snapshot: NSDiffableDataSourceSnapshot, - completion: (() -> Void)? = nil - ) { - self.applySnapshotUsingReloadData(snapshot, completion: completion) - } - - func applySnapshot( - _ snapshot: NSDiffableDataSourceSnapshot, - animated: Bool, - completion: (() -> Void)? = nil) { - - self.apply(snapshot, animatingDifferences: animated, completion: completion) - } -} diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift index 7edbfd2ac..5db98c218 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift @@ -24,7 +24,7 @@ extension MastodonPickServerViewModel { sectionHeaderSnapshot.appendSections([.main]) sectionHeaderSnapshot.appendItems(categoryPickerItems, toSection: .main) serverSectionHeaderView.delegate = pickServerServerSectionTableHeaderViewDelegate - serverSectionHeaderView.diffableDataSource?.applySnapshot(sectionHeaderSnapshot, animated: false) { [weak self] in + serverSectionHeaderView.diffableDataSource?.apply(sectionHeaderSnapshot, animatingDifferences: false) { [weak self] in guard let self = self else { return } guard let indexPath = self.serverSectionHeaderView.diffableDataSource?.indexPath(for: .all) else { return } self.serverSectionHeaderView.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredHorizontally) From 2cdd8af7c3e69ee748136aa86630a54b31e05da2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 17 Dec 2022 21:57:17 +0100 Subject: [PATCH 547/733] Remove workaround for tableviews --- Mastodon.xcodeproj/project.pbxproj | 4 --- .../UITableViewDiffableDataSource.swift | 25 ------------------- ...DiscoveryCommunityViewModel+Diffable.swift | 2 +- .../DiscoveryForYouViewModel+Diffable.swift | 2 +- .../DiscoveryNewsViewModel+Diffable.swift | 2 +- .../DiscoveryPostsViewModel+Diffable.swift | 2 +- .../Login/MastodonLoginViewController.swift | 2 +- ...astodonServerRulesViewModel+Diffable.swift | 2 +- .../Bookmark/BookmarkViewModel+Diffable.swift | 2 +- .../Favorite/FavoriteViewModel+Diffable.swift | 2 +- .../FollowedTags/FollowedTagsViewModel.swift | 2 +- .../UserTimelineViewModel+Diffable.swift | 2 +- .../ReportStatusViewModel+Diffable.swift | 2 +- 13 files changed, 11 insertions(+), 40 deletions(-) delete mode 100644 Mastodon/Extension/UITableViewDiffableDataSource.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 08fdba14b..338e1e80a 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -307,7 +307,6 @@ DB72602725E36A6F00235243 /* MastodonServerRulesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */; }; DB7274F4273BB9B200577D95 /* ListBatchFetchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7274F3273BB9B200577D95 /* ListBatchFetchViewModel.swift */; }; DB73B490261F030A002E9E9F /* SafariActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73B48F261F030A002E9E9F /* SafariActivity.swift */; }; - DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */; }; DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */; }; DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */; }; DB789A1225F9F2CC0071ACA0 /* ComposeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB789A1125F9F2CC0071ACA0 /* ComposeViewModel.swift */; }; @@ -880,7 +879,6 @@ DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonServerRulesViewModel.swift; sourceTree = ""; }; DB7274F3273BB9B200577D95 /* ListBatchFetchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListBatchFetchViewModel.swift; sourceTree = ""; }; DB73B48F261F030A002E9E9F /* SafariActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariActivity.swift; sourceTree = ""; }; - DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewDiffableDataSource.swift; sourceTree = ""; }; DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScheduler.swift; sourceTree = ""; }; DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; DB789A1125F9F2CC0071ACA0 /* ComposeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewModel.swift; sourceTree = ""; }; @@ -2283,7 +2281,6 @@ DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */, 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */, DBCC3B2F261440A50045B23D /* UITabBarController.swift */, - DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */, 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */, ); path = Extension; @@ -3406,7 +3403,6 @@ DB1E346825F518E20079D7DF /* CategoryPickerSection.swift in Sources */, DB7274F4273BB9B200577D95 /* ListBatchFetchViewModel.swift in Sources */, DB0618052785A73D0030EE79 /* RegisterItem.swift in Sources */, - DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */, DBB525642612C988002F1F29 /* MeProfileViewModel.swift in Sources */, DB3EA8EF281B837000598866 /* DiscoveryCommunityViewController+DataSourceProvider.swift in Sources */, DB6B74EF272FB55000C70B6E /* FollowerListViewController.swift in Sources */, diff --git a/Mastodon/Extension/UITableViewDiffableDataSource.swift b/Mastodon/Extension/UITableViewDiffableDataSource.swift deleted file mode 100644 index 6e3968a14..000000000 --- a/Mastodon/Extension/UITableViewDiffableDataSource.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// UITableViewDiffableDataSource.swift -// Mastodon -// -// Created by Cirno MainasuK on 2021-10-11. -// - -import UIKit - -// ref: https://www.jessesquires.com/blog/2021/07/08/diffable-data-source-behavior-changes-and-reconfiguring-cells-in-ios-15/ -extension UITableViewDiffableDataSource { - func reloadData( - snapshot: NSDiffableDataSourceSnapshot, - completion: (() -> Void)? = nil - ) { - self.applySnapshotUsingReloadData(snapshot, completion: completion) - } - - func applySnapshot( - _ snapshot: NSDiffableDataSourceSnapshot, - animated: Bool, - completion: (() -> Void)? = nil) { - self.apply(snapshot, animatingDifferences: animated, completion: completion) - } -} diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift index caa1f8460..a25dbaf1c 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+Diffable.swift @@ -59,7 +59,7 @@ extension DiscoveryCommunityViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift index af8d6ff47..31b14c55d 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift @@ -41,7 +41,7 @@ extension DiscoveryForYouViewModel { let items = records.map { DiscoveryItem.user($0) } snapshot.appendItems(items, toSection: .forYou) - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift index 11334dee8..deb8f48a7 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift @@ -52,7 +52,7 @@ extension DiscoveryNewsViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift index f36812538..99d68796d 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift @@ -59,7 +59,7 @@ extension DiscoveryPostsViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift index e9965fdde..9f9ce5d75 100644 --- a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift +++ b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift @@ -271,7 +271,7 @@ extension MastodonLoginViewController: MastodonLoginViewModelDelegate { snapshot.appendSections([MastodonLoginViewSection.servers]) snapshot.appendItems(viewModel.filteredServers) - dataSource?.applySnapshot(snapshot, animated: false) + dataSource?.apply(snapshot, animatingDifferences: false) OperationQueue.main.addOperation { let numberOfResults = viewModel.filteredServers.count diff --git a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewModel+Diffable.swift b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewModel+Diffable.swift index f6385a529..ecb868eb0 100644 --- a/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewModel+Diffable.swift +++ b/Mastodon/Scene/Onboarding/ServerRules/MastodonServerRulesViewModel+Diffable.swift @@ -21,6 +21,6 @@ extension MastodonServerRulesViewModel { return ServerRuleItem.rule(ruleContext) } snapshot.appendItems(ruleItems, toSection: .rules) - diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil) + diffableDataSource?.apply(snapshot, animatingDifferences: false) } } diff --git a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift index bb9148687..d52309e92 100644 --- a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift @@ -59,7 +59,7 @@ extension BookmarkViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift index e0f741f62..367a4d51f 100644 --- a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift @@ -59,7 +59,7 @@ extension FavoriteViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift index 75464092e..dbcf4d756 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift @@ -47,7 +47,7 @@ final class FollowedTagsViewModel: NSObject { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems(records.map {.hashtag($0) }) - self.diffableDataSource?.applySnapshot(snapshot, animated: true) + self.diffableDataSource?.apply(snapshot, animatingDifferences: true) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift index 4992e653a..67f2b8035 100644 --- a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift @@ -83,7 +83,7 @@ extension UserTimelineViewModel { } } - diffableDataSource.applySnapshot(snapshot, animated: false) + diffableDataSource.apply(snapshot, animatingDifferences: false) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift index 9879863d6..fce56a2b9 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift @@ -65,7 +65,7 @@ extension ReportStatusViewModel { break } - diffableDataSource.applySnapshot(snapshot, animated: false) { [weak self] in + diffableDataSource.apply(snapshot, animatingDifferences: false) { [weak self] in guard let self = self else { return } guard let diffableDataSource = self.diffableDataSource else { return } From cb1b35c008a8be8cd0871913d26a3dbb9cbeca4d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 18 Dec 2022 01:17:35 +0100 Subject: [PATCH 548/733] Fix iOS 15-deprecation-warning --- .../Sources/MastodonCore/Vendor/ItemProviderLoader.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Vendor/ItemProviderLoader.swift b/MastodonSDK/Sources/MastodonCore/Vendor/ItemProviderLoader.swift index 9899620fe..ad26e0ceb 100644 --- a/MastodonSDK/Sources/MastodonCore/Vendor/ItemProviderLoader.swift +++ b/MastodonSDK/Sources/MastodonCore/Vendor/ItemProviderLoader.swift @@ -48,13 +48,13 @@ extension ItemProviderLoader { let maxPixelSize: Int = 1536 // fit 120MB RAM limit #endif - let downsampleOptions = [ + let downsampleOptions: [CFString: Any] = [ kCGImageSourceCreateThumbnailFromImageAlways: true, kCGImageSourceCreateThumbnailWithTransform: true, kCGImageSourceThumbnailMaxPixelSize: maxPixelSize, - ] as CFDictionary + ] - guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) else { + guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions as CFDictionary) else { // fallback to loadItem when create thumbnail failure itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { image, error in if let error = error { @@ -77,7 +77,7 @@ extension ItemProviderLoader { } let data = NSMutableData() - guard let imageDestination = CGImageDestinationCreateWithData(data, kUTTypeJPEG, 1, nil) else { + guard let imageDestination = CGImageDestinationCreateWithData(data, UTType.jpeg.identifier as CFString, 1, nil) else { promise(.success(nil)) return } From 92a698fa3e5d85e2d536e02ae12053b1ad125406 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sat, 17 Dec 2022 21:20:03 -0500 Subject: [PATCH 549/733] fix: updated logo button's alt text to be more accessible --- .../Sources/MastodonLocalization/Generated/Strings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 984396754..0382fc4ee 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -715,7 +715,7 @@ public enum L10n { /// Tap to scroll to top and tap again to previous location public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint", fallback: "Tap to scroll to top and tap again to previous location") /// Logo Button - public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Logo Button") + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon Back to Top") } } } From bca33aeecd560ea6e9eb861c9aead759d7e7730d Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sat, 17 Dec 2022 21:26:35 -0500 Subject: [PATCH 550/733] fix: updated all other occurrences of Logo Button --- Localization/StringsConvertor/input/Base.lproj/app.json | 3 +-- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- Localization/app.json | 3 +-- .../HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift | 2 +- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/ckb.lproj/Localizable.strings | 2 +- .../Resources/en.lproj/Localizable.strings | 2 +- .../Resources/eu.lproj/Localizable.strings | 2 +- .../Resources/fi.lproj/Localizable.strings | 2 +- .../Resources/nl.lproj/Localizable.strings | 2 +- .../Resources/ru.lproj/Localizable.strings | 2 +- 26 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 8d4a5eae4..303c31feb 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -364,7 +364,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -726,7 +726,6 @@ }, "bookmark": { "title": "Bookmarks" - }, "followed_tags": { "title": "Followed Tags", diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 787bbea36..b2ff57508 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -360,7 +360,7 @@ "published": "بڵاوکرایەوە!", "Publishing": "پۆستەکە بڵاو دەکرێتەوە...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index fec3197be..dee710396 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 3113ada74..2365051c0 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 3113ada74..2365051c0 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 3113ada74..2365051c0 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 3da0d6a00..5fd4e5ad2 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -360,7 +360,7 @@ "published": "Argitaratua!", "Publishing": "Bidalketa argitaratzen...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 7dafe7fd1..52efd3e93 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Julkaistu!", "Publishing": "Julkaistaan julkaisua...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index f9414b6c0..82e80867c 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 4f2050792..ad90064de 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -360,7 +360,7 @@ "published": "Dipublikasikan!", "Publishing": "Mempublikasikan postingan...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 1ca18400b..25cefbc77 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 589c51d2d..bc460e24a 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -360,7 +360,7 @@ "published": "Gepubliceerd!", "Publishing": "Bericht publiceren...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 3113ada74..2365051c0 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 75a77184c..4b871656b 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 25314102a..d68f6dd16 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -360,7 +360,7 @@ "published": "Опубликовано!", "Publishing": "Публикуем пост...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index a4542b9e9..4733c514d 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 3113ada74..2365051c0 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/app.json b/Localization/app.json index 2abc74f74..bbce4e85e 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -740,7 +740,6 @@ }, "bookmark": { "title": "Bookmarks" - }, "followed_tags": { "title": "Followed Tags", diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 38b80fe28..536890bdc 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,7 +103,7 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Logo Button" // TODO :i18n + logoButton.accessibilityLabel = "Mastodon Back to Top" // TODO :i18n logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" case .newPostButton: configureButton( diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 84480c3aa..5f86729b5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -252,7 +252,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 4e76e20fb..83ea4141a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -233,7 +233,7 @@ "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "پۆستە نوێکان ببینە"; "Scene.HomeTimeline.NavigationBarState.Offline" = "دەرهێڵ"; "Scene.HomeTimeline.NavigationBarState.Published" = "بڵاوکرایەوە!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 9afcd60d9..4135a57dd 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -242,7 +242,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index e2985112e..12c882bec 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -234,7 +234,7 @@ Mastodonera igo."; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index 7902fb6eb..b977bc385 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -234,7 +234,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Uusia julkaisuja"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Yhteydetön"; "Scene.HomeTimeline.NavigationBarState.Published" = "Julkaistu!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 0d8f1dd0f..d63625afc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -229,7 +229,7 @@ klik op de link om uw account te bevestigen."; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 2ad16cb77..ed46076ef 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -245,7 +245,7 @@ "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Показать новые"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Не в сети"; "Scene.HomeTimeline.NavigationBarState.Published" = "Опубликовано!"; From f1fd49a25c83d51c10d56ff57939e87ed91bb5f7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:36 +0100 Subject: [PATCH 551/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 37d593f60..b9f954047 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -467,6 +467,7 @@ "followers": "sledilcev" }, "fields": { + "joined": "Joined", "add_row": "Dodaj vrstico", "placeholder": { "label": "Oznaka", From 309e7a6071e42e269af2c326a3f8768497d5502c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:37 +0100 Subject: [PATCH 552/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 20acba9c1..cc0a5c4da 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -467,6 +467,7 @@ "followers": "跟隨者" }, "fields": { + "joined": "Joined", "add_row": "新增列", "placeholder": { "label": "標籤", From be1e17d787d4d124fdf9f85b83431ac7a97f31a5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:37 +0100 Subject: [PATCH 553/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index cf0d25a6a..48091c0d5 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -467,6 +467,7 @@ "followers": "người theo dõi" }, "fields": { + "joined": "Joined", "add_row": "Thêm hàng", "placeholder": { "label": "Nhãn", From ea4e58b64476b23a3be1b10bacb032c5b37391cb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:38 +0100 Subject: [PATCH 554/733] New translations app.json (Kabyle) --- Localization/StringsConvertor/input/kab.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 774755596..fcb8151f9 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -467,6 +467,7 @@ "followers": "imeḍfaren" }, "fields": { + "joined": "Joined", "add_row": "Rnu izirig", "placeholder": { "label": "Tabzimt", From b11469b3f7591b6a72bd510b2e45174f74d009bf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:39 +0100 Subject: [PATCH 555/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index b2b10ce63..b780c4fff 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -467,6 +467,7 @@ "followers": "팔로워" }, "fields": { + "joined": "Joined", "add_row": "행 추가", "placeholder": { "label": "라벨", From aa7bfc699cf4c1a8af6b05d12aff71585d3c4053 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:40 +0100 Subject: [PATCH 556/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 6a2676635..09f4778eb 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -467,6 +467,7 @@ "followers": "följare" }, "fields": { + "joined": "Joined", "add_row": "Lägg till rad", "placeholder": { "label": "Etikett", From 32f193281a134da115f0c07bf8e407dcfcfc2d9a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:42 +0100 Subject: [PATCH 557/733] New translations app.json (French) --- Localization/StringsConvertor/input/fr.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index c9597cb35..c1f553a79 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -467,6 +467,7 @@ "followers": "abonnés" }, "fields": { + "joined": "Joined", "add_row": "Ajouter une rangée", "placeholder": { "label": "Étiquette", From 014cba2498262eab0124db39c289db0d4a1d3e0f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:43 +0100 Subject: [PATCH 558/733] New translations app.json (Turkish) --- Localization/StringsConvertor/input/tr.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index c0078755a..640aa35c0 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -467,6 +467,7 @@ "followers": "takipçi" }, "fields": { + "joined": "Joined", "add_row": "Satır Ekle", "placeholder": { "label": "Etiket", From 3b0b627074493acd4a4822affca50ed2020ab572 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:44 +0100 Subject: [PATCH 559/733] New translations app.json (Czech) --- Localization/StringsConvertor/input/cs.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 306eabbdb..974ac12dc 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -467,6 +467,7 @@ "followers": "sledující" }, "fields": { + "joined": "Joined", "add_row": "Přidat řádek", "placeholder": { "label": "Označení", From 44ded04631a9306606fdaf043b5e19c2ef23a65c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:45 +0100 Subject: [PATCH 560/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 56a12dadd..6b4f8f75c 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -467,6 +467,7 @@ "followers": "підписників" }, "fields": { + "joined": "Joined", "add_row": "Додати рядок", "placeholder": { "label": "Позначка", From 3fe9b9291d2ded068f17a5e6b42a2956f9b724c4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:46 +0100 Subject: [PATCH 561/733] New translations app.json (Scottish Gaelic) --- Localization/StringsConvertor/input/gd.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 40a1012a9..659572e8f 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -467,6 +467,7 @@ "followers": "luchd-leantainn" }, "fields": { + "joined": "Joined", "add_row": "Cuir ràgh ris", "placeholder": { "label": "Leubail", From 804ed9d3cf0544a9e7caab281e955f5ea22caeb4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:46 +0100 Subject: [PATCH 562/733] New translations app.json (Romanian) --- Localization/StringsConvertor/input/ro.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index cc266098a..de8a2c00a 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From bba4fb3606dd76108c622e331d19ea2e65725fd9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:47 +0100 Subject: [PATCH 563/733] New translations app.json (Spanish) --- Localization/StringsConvertor/input/es.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 6c42cc561..205a0c4df 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidores" }, "fields": { + "joined": "Joined", "add_row": "Añadir Fila", "placeholder": { "label": "Nombre para el campo", From 5d572d1ffc84ea69e4c50864a61391a007ebfddf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:48 +0100 Subject: [PATCH 564/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index ff3602766..42d3bfc5d 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -467,6 +467,7 @@ "followers": "مُتابِع" }, "fields": { + "joined": "Joined", "add_row": "إضافة صف", "placeholder": { "label": "التسمية", From f1ca440e351f752e714c49e9c8432486ca12f726 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:50 +0100 Subject: [PATCH 565/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 4eeffd728..0a364b181 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidors" }, "fields": { + "joined": "Joined", "add_row": "Afegeix fila", "placeholder": { "label": "Etiqueta", From 1a5b762fd62734fd46cd37c6e022a06df7eb7c39 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:51 +0100 Subject: [PATCH 566/733] New translations app.json (Danish) --- Localization/StringsConvertor/input/da.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 3b27fd65a..52f1fa405 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From db45dbdd0f6fe5cb1eabd968c1f7c5005e557ac8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:53 +0100 Subject: [PATCH 567/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 74ba8d657..3157987e9 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -467,6 +467,7 @@ "followers": "Folgende" }, "fields": { + "joined": "Joined", "add_row": "Zeile hinzufügen", "placeholder": { "label": "Bezeichnung", From c5959170291005686a79138fcde222a7cf5700db Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:53 +0100 Subject: [PATCH 568/733] New translations app.json (Basque) --- Localization/StringsConvertor/input/eu.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index dc8b14108..c07692277 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -467,6 +467,7 @@ "followers": "jarraitzaile" }, "fields": { + "joined": "Joined", "add_row": "Gehitu errenkada", "placeholder": { "label": "Etiketa", From 0fbae5e76e1cb63045360a53e8a0dc8e7452719a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:54 +0100 Subject: [PATCH 569/733] New translations app.json (Finnish) --- Localization/StringsConvertor/input/fi.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 9ceb6da6d..721c25636 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seuraajat" }, "fields": { + "joined": "Joined", "add_row": "Lisää rivi", "placeholder": { "label": "Nimi", From b5e5c8d096572a7f042f0cba41430cede42455c3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:55 +0100 Subject: [PATCH 570/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 106ab151f..d86287025 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguaci" }, "fields": { + "joined": "Joined", "add_row": "Aggiungi riga", "placeholder": { "label": "Etichetta", From 4ddc20be000b0df34b996b8918046d424d230fd8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:57 +0100 Subject: [PATCH 571/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 1b3184e9f..c716b18ff 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -467,6 +467,7 @@ "followers": "フォロワー" }, "fields": { + "joined": "Joined", "add_row": "行追加", "placeholder": { "label": "ラベル", From 2ad19c5b93ea86cf516fc45e38d351a4e0c4b5ec Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:57 +0100 Subject: [PATCH 572/733] New translations app.json (Dutch) --- Localization/StringsConvertor/input/nl.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 32a6fe3e8..30ed3b56a 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -467,6 +467,7 @@ "followers": "volgers" }, "fields": { + "joined": "Joined", "add_row": "Rij Toevoegen", "placeholder": { "label": "Etiket", From 6f1018fec2ebb37c6ee52e9032fe8c1e81afe548 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:58 +0100 Subject: [PATCH 573/733] New translations app.json (Portuguese) --- Localization/StringsConvertor/input/pt.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 3b27fd65a..52f1fa405 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From 4b3928d75ee4dacd7be304dab1de68815b5fa36b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:31:59 +0100 Subject: [PATCH 574/733] New translations app.json (Russian) --- Localization/StringsConvertor/input/ru.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 50931c05c..588e70d1e 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -467,6 +467,7 @@ "followers": "подписчики" }, "fields": { + "joined": "Joined", "add_row": "Добавить строку", "placeholder": { "label": "Ярлык", From 7fc3c146d3f775643cc002852d8c8afeb44cf143 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:00 +0100 Subject: [PATCH 575/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index f49311df4..6329a7990 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -467,6 +467,7 @@ "followers": "关注者" }, "fields": { + "joined": "Joined", "add_row": "添加", "placeholder": { "label": "标签", From 75e531bd256d69877c585ce3da4ab14c147ba85f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:01 +0100 Subject: [PATCH 576/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 3b27fd65a..52f1fa405 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From 54cb50c7c3c1360ec1d20dbd318e09216e8e2ec2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:02 +0100 Subject: [PATCH 577/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 3f509a616..5e772d6c6 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidoras" }, "fields": { + "joined": "Joined", "add_row": "Engadir fila", "placeholder": { "label": "Etiqueta", From ca82e97af130ab0b2bd26484b01a48ec85ad7f01 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:03 +0100 Subject: [PATCH 578/733] New translations app.json (Portuguese, Brazilian) --- Localization/StringsConvertor/input/pt-BR.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 098304cdb..1eb88370e 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidores" }, "fields": { + "joined": "Joined", "add_row": "Adicionar linha", "placeholder": { "label": "Descrição", From 357e70fc31d30abffe6968eb41e2583b47553c79 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:04 +0100 Subject: [PATCH 579/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index b6ef46040..bf43a9405 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -467,6 +467,7 @@ "followers": "pengikut" }, "fields": { + "joined": "Joined", "add_row": "Tambah Baris", "placeholder": { "label": "Label", From 53f92959e9cfb970082e7636a752e47cc3dbc599 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:05 +0100 Subject: [PATCH 580/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 5cc12594c..bf912f886 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidores" }, "fields": { + "joined": "Joined", "add_row": "Agregar fila", "placeholder": { "label": "Nombre de campo", From 7367489b22b1869e2231337f510136d25437f658 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:06 +0100 Subject: [PATCH 581/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 4c17d59c3..7ce8df356 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -467,6 +467,7 @@ "followers": "ผู้ติดตาม" }, "fields": { + "joined": "Joined", "add_row": "เพิ่มแถว", "placeholder": { "label": "ป้ายชื่อ", From 3b97cd8c84452e4bc5bc81a3f35db101eff441ec Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:07 +0100 Subject: [PATCH 582/733] New translations app.json (Latvian) --- Localization/StringsConvertor/input/lv.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 6c474a628..515c2b721 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -467,6 +467,7 @@ "followers": "sekottāji" }, "fields": { + "joined": "Joined", "add_row": "Pievienot rindu", "placeholder": { "label": "Label", From 1ebc797080655437c0c351c9bce2b598d983d63c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:08 +0100 Subject: [PATCH 583/733] New translations app.json (Hindi) --- Localization/StringsConvertor/input/hi.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index a226a4b0c..a51761eeb 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From f9b50dd1ac7ccb5cb995b6e49964a0cf5e108507 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:09 +0100 Subject: [PATCH 584/733] New translations app.json (English, United States) --- Localization/StringsConvertor/input/en-US.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 3b27fd65a..52f1fa405 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From 7ca8d8c8ebab8aae0a8379c40d26e6c3c83dd296 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:10 +0100 Subject: [PATCH 585/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 8b7dc902c..e6a0d40ee 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -467,6 +467,7 @@ "followers": "dilynwyr" }, "fields": { + "joined": "Joined", "add_row": "Ychwanegu Rhes", "placeholder": { "label": "Label", From 21839d8f7f31b3c07a2d7cf9062c056635920faa Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:11 +0100 Subject: [PATCH 586/733] New translations app.json (Sinhala) --- Localization/StringsConvertor/input/si.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index a2a50619a..9d377d5d2 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "නම්පත", From e88a1be3001d1f97cca906fcf5aabf569a106560 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:12 +0100 Subject: [PATCH 587/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index e40b12687..9bb66734d 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -467,6 +467,7 @@ "followers": "şopîner" }, "fields": { + "joined": "Joined", "add_row": "Rêzê tevlî bike", "placeholder": { "label": "Nîşan", From 846e24f0e89a0bedfa26d9fba8b27c428d1f652d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:13 +0100 Subject: [PATCH 588/733] New translations app.json (Sorani (Kurdish)) --- Localization/StringsConvertor/input/ckb.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 8bf937533..b04834856 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -467,6 +467,7 @@ "followers": "شوێنکەوتوو" }, "fields": { + "joined": "Joined", "add_row": "ڕیز زیاد بکە", "placeholder": { "label": "ناونیشان", From d294b5dd37a0dc084e4e63607b4a628d8dd4674f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:14 +0100 Subject: [PATCH 589/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index f3015199b..8437a68ba 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -467,6 +467,7 @@ "followers": "fylgjendur" }, "fields": { + "joined": "Joined", "add_row": "Bæta við röð", "placeholder": { "label": "Skýring", From 03426545b433aaf6f9241806111ea2955933ebfc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:15 +0100 Subject: [PATCH 590/733] New translations app.json (Burmese) --- Localization/StringsConvertor/input/my.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index c05ab2f32..e5ed501c5 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From eb2d28b43251352ae3602ee387b6ca8baedb2284 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:16 +0100 Subject: [PATCH 591/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 6f88fe606..09d251137 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -467,6 +467,7 @@ "followers": "seguidores" }, "fields": { + "joined": "Joined", "add_row": "Anyadir Ringlera", "placeholder": { "label": "Nombre pa lo campo", From e7b56f877b137ed09038c7a56c29bbfb893ae662 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 14:32:17 +0100 Subject: [PATCH 592/733] New translations app.json (Hebrew) --- Localization/StringsConvertor/input/he.lproj/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index f93b52208..b2d679b61 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -467,6 +467,7 @@ "followers": "followers" }, "fields": { + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", From 0f3f3396c2c1dec7531141c165c9adf5d6b7b97e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 15:32:35 +0100 Subject: [PATCH 593/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 09f4778eb..cd8320db5 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -467,7 +467,7 @@ "followers": "följare" }, "fields": { - "joined": "Joined", + "joined": "Gick med", "add_row": "Lägg till rad", "placeholder": { "label": "Etikett", From c96ed75c3f0ece9ba5045f61be2f3123bd9c98de Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 15:32:36 +0100 Subject: [PATCH 594/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 0a364b181..a30726151 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -467,7 +467,7 @@ "followers": "seguidors" }, "fields": { - "joined": "Joined", + "joined": "S'hi va unir", "add_row": "Afegeix fila", "placeholder": { "label": "Etiqueta", From b438fb3e6ba19343eb466703020f3de2a26fab2a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 15:32:37 +0100 Subject: [PATCH 595/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 3157987e9..73d9e5605 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -467,7 +467,7 @@ "followers": "Folgende" }, "fields": { - "joined": "Joined", + "joined": "Beigetreten", "add_row": "Zeile hinzufügen", "placeholder": { "label": "Bezeichnung", From e4027bbe68a1e4efd7aca6af3058088e5b4ddc38 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:33:13 -0500 Subject: [PATCH 596/733] fix: swapped to correct alt for the image. --- Localization/StringsConvertor/input/Base.lproj/app.json | 2 +- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- Localization/app.json | 2 +- .../HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 2 +- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/ckb.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/en.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/eu.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/fi.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/nl.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/ru.lproj/Localizable.strings | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 303c31feb..4093cbde8 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -364,7 +364,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index b2ff57508..3738f090c 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -360,7 +360,7 @@ "published": "بڵاوکرایەوە!", "Publishing": "پۆستەکە بڵاو دەکرێتەوە...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index dee710396..b8a6e080a 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 2365051c0..6f96c652d 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 2365051c0..6f96c652d 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 2365051c0..6f96c652d 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 5fd4e5ad2..45a896276 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -360,7 +360,7 @@ "published": "Argitaratua!", "Publishing": "Bidalketa argitaratzen...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 52efd3e93..06d1088c0 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Julkaistu!", "Publishing": "Julkaistaan julkaisua...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 82e80867c..f49840981 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index ad90064de..59a593a70 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -360,7 +360,7 @@ "published": "Dipublikasikan!", "Publishing": "Mempublikasikan postingan...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 25cefbc77..60209a719 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index bc460e24a..327fb42d6 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -360,7 +360,7 @@ "published": "Gepubliceerd!", "Publishing": "Bericht publiceren...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 2365051c0..6f96c652d 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 4b871656b..6a13bb95f 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index d68f6dd16..1e2dd3100 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -360,7 +360,7 @@ "published": "Опубликовано!", "Publishing": "Публикуем пост...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 4733c514d..dfa5707dc 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 2365051c0..6f96c652d 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/app.json b/Localization/app.json index bbce4e85e..215215639 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 536890bdc..69f04a956 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,7 +103,7 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Mastodon Back to Top" // TODO :i18n + logoButton.accessibilityLabel = "Mastodon" // TODO :i18n logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" case .newPostButton: configureButton( diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 0382fc4ee..163d32a4d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -715,7 +715,7 @@ public enum L10n { /// Tap to scroll to top and tap again to previous location public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint", fallback: "Tap to scroll to top and tap again to previous location") /// Logo Button - public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon Back to Top") + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon") } } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 5f86729b5..ee8b1f0a2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -252,7 +252,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 83ea4141a..99563da9f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -233,7 +233,7 @@ "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "پۆستە نوێکان ببینە"; "Scene.HomeTimeline.NavigationBarState.Offline" = "دەرهێڵ"; "Scene.HomeTimeline.NavigationBarState.Published" = "بڵاوکرایەوە!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 4135a57dd..ba899c6f0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -242,7 +242,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index 12c882bec..845ae6407 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -234,7 +234,7 @@ Mastodonera igo."; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index b977bc385..ac7fb212c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -234,7 +234,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Uusia julkaisuja"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Yhteydetön"; "Scene.HomeTimeline.NavigationBarState.Published" = "Julkaistu!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index d63625afc..824d24ab1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -229,7 +229,7 @@ klik op de link om uw account te bevestigen."; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index ed46076ef..1f9232f94 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -245,7 +245,7 @@ "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Показать новые"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Не в сети"; "Scene.HomeTimeline.NavigationBarState.Published" = "Опубликовано!"; From 8ef450b2d1a4e977dc95ecf0aff883d4dae7bbdc Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:35:21 -0500 Subject: [PATCH 597/733] fix: updated formatting --- Localization/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/app.json b/Localization/app.json index 215215639..46087134e 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } From b80c6f74df7f11128f9718c64e92358a21c235cc Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:48:21 -0500 Subject: [PATCH 598/733] Revert "fix: updated formatting" This reverts commit 8ef450b2d1a4e977dc95ecf0aff883d4dae7bbdc. --- Localization/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/app.json b/Localization/app.json index 46087134e..215215639 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } From d621763a85eac9f0e717d936114d6865aa424dc7 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:48:23 -0500 Subject: [PATCH 599/733] Revert "fix: swapped to correct alt for the image." This reverts commit e4027bbe68a1e4efd7aca6af3058088e5b4ddc38. --- Localization/StringsConvertor/input/Base.lproj/app.json | 2 +- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- Localization/app.json | 2 +- .../HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 2 +- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/ckb.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/en.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/eu.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/fi.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/nl.lproj/Localizable.strings | 2 +- .../MastodonLocalization/Resources/ru.lproj/Localizable.strings | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 4093cbde8..303c31feb 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -364,7 +364,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 3738f090c..b2ff57508 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -360,7 +360,7 @@ "published": "بڵاوکرایەوە!", "Publishing": "پۆستەکە بڵاو دەکرێتەوە...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index b8a6e080a..dee710396 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 6f96c652d..2365051c0 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 6f96c652d..2365051c0 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 6f96c652d..2365051c0 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 45a896276..5fd4e5ad2 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -360,7 +360,7 @@ "published": "Argitaratua!", "Publishing": "Bidalketa argitaratzen...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 06d1088c0..52efd3e93 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Julkaistu!", "Publishing": "Julkaistaan julkaisua...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index f49840981..82e80867c 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 59a593a70..ad90064de 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -360,7 +360,7 @@ "published": "Dipublikasikan!", "Publishing": "Mempublikasikan postingan...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 60209a719..25cefbc77 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 327fb42d6..bc460e24a 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -360,7 +360,7 @@ "published": "Gepubliceerd!", "Publishing": "Bericht publiceren...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 6f96c652d..2365051c0 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 6a13bb95f..4b871656b 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 1e2dd3100..d68f6dd16 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -360,7 +360,7 @@ "published": "Опубликовано!", "Publishing": "Публикуем пост...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index dfa5707dc..4733c514d 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 6f96c652d..2365051c0 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/app.json b/Localization/app.json index 215215639..bbce4e85e 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "Mastodon Back to Top", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 69f04a956..536890bdc 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,7 +103,7 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Mastodon" // TODO :i18n + logoButton.accessibilityLabel = "Mastodon Back to Top" // TODO :i18n logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" case .newPostButton: configureButton( diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 163d32a4d..0382fc4ee 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -715,7 +715,7 @@ public enum L10n { /// Tap to scroll to top and tap again to previous location public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint", fallback: "Tap to scroll to top and tap again to previous location") /// Logo Button - public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon") + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon Back to Top") } } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index ee8b1f0a2..5f86729b5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -252,7 +252,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 99563da9f..83ea4141a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -233,7 +233,7 @@ "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "پۆستە نوێکان ببینە"; "Scene.HomeTimeline.NavigationBarState.Offline" = "دەرهێڵ"; "Scene.HomeTimeline.NavigationBarState.Published" = "بڵاوکرایەوە!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index ba899c6f0..4135a57dd 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -242,7 +242,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index 845ae6407..12c882bec 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -234,7 +234,7 @@ Mastodonera igo."; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index ac7fb212c..b977bc385 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -234,7 +234,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Uusia julkaisuja"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Yhteydetön"; "Scene.HomeTimeline.NavigationBarState.Published" = "Julkaistu!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 824d24ab1..d63625afc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -229,7 +229,7 @@ klik op de link om uw account te bevestigen."; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 1f9232f94..ed46076ef 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -245,7 +245,7 @@ "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Показать новые"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Не в сети"; "Scene.HomeTimeline.NavigationBarState.Published" = "Опубликовано!"; From 9f53dbdc0a1fc9bfe63549200beea2df5b78ba8e Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:48:25 -0500 Subject: [PATCH 600/733] Revert "fix: updated all other occurrences of Logo Button" This reverts commit bca33aeecd560ea6e9eb861c9aead759d7e7730d. --- Localization/StringsConvertor/input/Base.lproj/app.json | 3 ++- Localization/StringsConvertor/input/ckb.lproj/app.json | 2 +- Localization/StringsConvertor/input/cy.lproj/app.json | 2 +- Localization/StringsConvertor/input/da.lproj/app.json | 2 +- Localization/StringsConvertor/input/en-US.lproj/app.json | 2 +- Localization/StringsConvertor/input/en.lproj/app.json | 2 +- Localization/StringsConvertor/input/eu.lproj/app.json | 2 +- Localization/StringsConvertor/input/fi.lproj/app.json | 2 +- Localization/StringsConvertor/input/hi.lproj/app.json | 2 +- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- Localization/StringsConvertor/input/lv.lproj/app.json | 2 +- Localization/StringsConvertor/input/nl.lproj/app.json | 2 +- Localization/StringsConvertor/input/pt.lproj/app.json | 2 +- Localization/StringsConvertor/input/ro.lproj/app.json | 2 +- Localization/StringsConvertor/input/ru.lproj/app.json | 2 +- Localization/StringsConvertor/input/si.lproj/app.json | 2 +- Localization/StringsConvertor/input/uk.lproj/app.json | 2 +- Localization/app.json | 3 ++- .../HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift | 2 +- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/ckb.lproj/Localizable.strings | 2 +- .../Resources/en.lproj/Localizable.strings | 2 +- .../Resources/eu.lproj/Localizable.strings | 2 +- .../Resources/fi.lproj/Localizable.strings | 2 +- .../Resources/nl.lproj/Localizable.strings | 2 +- .../Resources/ru.lproj/Localizable.strings | 2 +- 26 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 303c31feb..8d4a5eae4 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -364,7 +364,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -726,6 +726,7 @@ }, "bookmark": { "title": "Bookmarks" + }, "followed_tags": { "title": "Followed Tags", diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index b2ff57508..787bbea36 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -360,7 +360,7 @@ "published": "بڵاوکرایەوە!", "Publishing": "پۆستەکە بڵاو دەکرێتەوە...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index dee710396..fec3197be 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 2365051c0..3113ada74 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 2365051c0..3113ada74 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 2365051c0..3113ada74 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 5fd4e5ad2..3da0d6a00 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -360,7 +360,7 @@ "published": "Argitaratua!", "Publishing": "Bidalketa argitaratzen...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 52efd3e93..7dafe7fd1 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Julkaistu!", "Publishing": "Julkaistaan julkaisua...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 82e80867c..f9414b6c0 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index ad90064de..4f2050792 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -360,7 +360,7 @@ "published": "Dipublikasikan!", "Publishing": "Mempublikasikan postingan...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 25cefbc77..1ca18400b 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index bc460e24a..589c51d2d 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -360,7 +360,7 @@ "published": "Gepubliceerd!", "Publishing": "Bericht publiceren...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 2365051c0..3113ada74 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 4b871656b..75a77184c 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index d68f6dd16..25314102a 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -360,7 +360,7 @@ "published": "Опубликовано!", "Publishing": "Публикуем пост...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 4733c514d..a4542b9e9 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 2365051c0..3113ada74 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -360,7 +360,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/Localization/app.json b/Localization/app.json index bbce4e85e..2abc74f74 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Mastodon Back to Top", + "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -740,6 +740,7 @@ }, "bookmark": { "title": "Bookmarks" + }, "followed_tags": { "title": "Followed Tags", diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 536890bdc..38b80fe28 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,7 +103,7 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Mastodon Back to Top" // TODO :i18n + logoButton.accessibilityLabel = "Logo Button" // TODO :i18n logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" case .newPostButton: configureButton( diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 5f86729b5..84480c3aa 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -252,7 +252,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 83ea4141a..4e76e20fb 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -233,7 +233,7 @@ "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "پۆستە نوێکان ببینە"; "Scene.HomeTimeline.NavigationBarState.Offline" = "دەرهێڵ"; "Scene.HomeTimeline.NavigationBarState.Published" = "بڵاوکرایەوە!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 4135a57dd..9afcd60d9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -242,7 +242,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index 12c882bec..e2985112e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -234,7 +234,7 @@ Mastodonera igo."; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index b977bc385..7902fb6eb 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -234,7 +234,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Uusia julkaisuja"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Yhteydetön"; "Scene.HomeTimeline.NavigationBarState.Published" = "Julkaistu!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index d63625afc..0d8f1dd0f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -229,7 +229,7 @@ klik op de link om uw account te bevestigen."; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index ed46076ef..2ad16cb77 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -245,7 +245,7 @@ "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon Back to Top"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Показать новые"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Не в сети"; "Scene.HomeTimeline.NavigationBarState.Published" = "Опубликовано!"; From 26488390f1d7b1c5f88136873df1008baec0f640 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:48:27 -0500 Subject: [PATCH 601/733] Revert "fix: updated logo button's alt text to be more accessible" This reverts commit 92a698fa3e5d85e2d536e02ae12053b1ad125406. --- .../Sources/MastodonLocalization/Generated/Strings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 0382fc4ee..984396754 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -715,7 +715,7 @@ public enum L10n { /// Tap to scroll to top and tap again to previous location public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint", fallback: "Tap to scroll to top and tap again to previous location") /// Logo Button - public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon Back to Top") + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Logo Button") } } } From 44e34670ec612ea0c1af0dbb08e8a77ec37ae1f5 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:49:00 -0500 Subject: [PATCH 602/733] fix: updated the singular file needing an update --- Localization/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/app.json b/Localization/app.json index 2abc74f74..4464dcc7a 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } From 955389efad78c28a92f30e10369cd99ca3398810 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Sun, 18 Dec 2022 10:51:18 -0500 Subject: [PATCH 603/733] fix: ran swiftgen --- .../StringsConvertor/input/Base.lproj/app.json | 18 ++++++++++++++++-- .../Resources/Base.lproj/Localizable.strings | 10 +++++----- .../Resources/en.lproj/Localizable.strings | 10 +--------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 8d4a5eae4..4464dcc7a 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -92,7 +97,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -172,6 +181,11 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s", + "unknown_language": "Unknown", + "show_original": "Shown Original" } }, "friendship": { @@ -364,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 84480c3aa..dab42f8ad 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -22,9 +22,9 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; -"Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; @@ -133,7 +133,7 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; "Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; @@ -252,7 +252,7 @@ uploaded to Mastodon."; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; @@ -479,4 +479,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 9afcd60d9..2a3f1efbf 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -22,9 +22,6 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; -"Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; -"Common.Alerts.TranslationFailed.Button" = "OK"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; @@ -62,8 +59,6 @@ Please check your internet connection."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; -"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; -"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; "Common.Controls.Friendship.Block" = "Block"; @@ -129,9 +124,6 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; -"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; -"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Replied to %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; @@ -469,4 +461,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file From 0ef8f003e3199b5a45225a25a84da7f0fbf534f5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 16:56:40 +0100 Subject: [PATCH 604/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index cc0a5c4da..b07fc0a7b 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -467,7 +467,7 @@ "followers": "跟隨者" }, "fields": { - "joined": "Joined", + "joined": "加入時間", "add_row": "新增列", "placeholder": { "label": "標籤", From 4bd0cfad6046e3934e2a4c874bd856dbaac833a2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 16:56:41 +0100 Subject: [PATCH 605/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 52f1fa405..402ffc117 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -378,7 +378,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -467,7 +467,7 @@ "followers": "followers" }, "fields": { - "joined": "Joined", + "joined": "Liitytty", "add_row": "Add Row", "placeholder": { "label": "Label", From f5a2c0de353822d9709c431b7dc01a6c6eabad15 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 18:07:30 +0100 Subject: [PATCH 606/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 48091c0d5..c0b04c897 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -467,7 +467,7 @@ "followers": "người theo dõi" }, "fields": { - "joined": "Joined", + "joined": "Đã tham gia", "add_row": "Thêm hàng", "placeholder": { "label": "Nhãn", From 147f7f9eb851a3a96c907833fa746c43e3d5dd8d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 18:07:30 +0100 Subject: [PATCH 607/733] New translations app.json (French) --- .../StringsConvertor/input/fr.lproj/app.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index c1f553a79..59be72b68 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -54,7 +54,7 @@ }, "translation_failed": { "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "message": "La traduction a échoué. Peut-être que l'administrateur n'a pas activé les traductions sur ce serveur ou que ce serveur utilise une ancienne version de Mastodon où les traductions ne sont pas encore prises en charge.", "button": "OK" } }, @@ -83,7 +83,7 @@ "sign_up": "Créer un compte", "see_more": "Voir plus", "preview": "Aperçu", - "copy": "Copy", + "copy": "Copier", "share": "Partager", "share_user": "Partager %s", "share_post": "Partager la publication", @@ -99,8 +99,8 @@ "settings": "Paramètres", "delete": "Supprimer", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Traduit depuis %s", + "unknown_language": "Inconnu" } }, "tabs": { @@ -142,7 +142,7 @@ "sensitive_content": "Contenu sensible", "media_content_warning": "Tapotez n’importe où pour révéler la publication", "tap_to_reveal": "Appuyer pour afficher", - "load_embed": "Load Embed", + "load_embed": "Charger l'intégration", "link_via_user": "%s via %s", "poll": { "vote": "Voter", @@ -165,7 +165,7 @@ "show_image": "Afficher l’image", "show_gif": "Afficher le GIF", "show_video_player": "Afficher le lecteur vidéo", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Partager le lien dans le message", "tap_then_hold_to_show_menu": "Appuyez et maintenez pour afficher le menu" }, "tag": { @@ -183,9 +183,9 @@ "direct": "Seul·e l’utilisateur·rice mentionnée peut voir ce message." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Traduit depuis %s", + "unknown_language": "Inconnu", + "show_original": "Afficher l’original" } }, "friendship": { @@ -467,7 +467,7 @@ "followers": "abonnés" }, "fields": { - "joined": "Joined", + "joined": "Ici depuis", "add_row": "Ajouter une rangée", "placeholder": { "label": "Étiquette", From 4b94ccba664da043456df5dbd82efdfbc7ae452c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 18:07:31 +0100 Subject: [PATCH 608/733] New translations app.json (Latvian) --- .../StringsConvertor/input/lv.lproj/app.json | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 515c2b721..9b1a8c074 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -6,30 +6,30 @@ "please_try_again_later": "Lūdzu, mēģiniet vēlreiz vēlāk." }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "Reģistrācijas Neveiksme" }, "server_error": { "title": "Servera kļūda" }, "vote_failure": { - "title": "Vote Failure", + "title": "Balsošanas Neveiksme", "poll_ended": "Balsošana beidzās" }, "discard_post_content": { "title": "Atmest malnrakstu", - "message": "Confirm to discard composed post content." + "message": "Apstiprini, lai atmestu izveidotās ziņas saturu." }, "publish_post_failure": { - "title": "Publish Failure", - "message": "Failed to publish the post.\nPlease check your internet connection.", + "title": "Publicēšanas Neveiksme", + "message": "Neizdevās publicēt ziņu.\nLūdzu, pārbaudi savu interneta savienojumu.", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", - "more_than_one_video": "Cannot attach more than one video." + "video_attach_with_photo": "Nevar pievienot videoklipu ziņai, kurā jau ir attēli.", + "more_than_one_video": "Nevar pievienot vairāk kā vienu video." } }, "edit_profile_failure": { - "title": "Edit Profile Error", - "message": "Cannot edit profile. Please try again." + "title": "Profila Rediģēšanas Kļūda", + "message": "Nevar rediģēt profilu. Lūdzu mēģini vēlreiz." }, "sign_out": { "title": "Iziet", @@ -37,25 +37,25 @@ "confirm": "Iziet" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", - "block_entire_domain": "Block Domain" + "title": "Vai tiešām tiešām vēlies bloķēt visu %s? Vairumā gadījumu pietiek ar dažiem mērķtiecīgiem blokiem vai klusinātājiem, un tie ir vēlami. Tu neredzēsi saturu no šī domēna, un visi tavi sekotāji no šī domēna tiks noņemti.", + "block_entire_domain": "Bloķēt Domēnu" }, "save_photo_failure": { - "title": "Save Photo Failure", - "message": "Please enable the photo library access permission to save the photo." + "title": "Attēla Saglabāšanas Kļūda", + "message": "Lai saglabātu fotoattēlu, lūdzu, iespējo fotoattēlu bibliotēkas piekļuves atļauju." }, "delete_post": { "title": "Dzēst ierakstu", "message": "Vai tiešām vēlies dzēst ierakstu?" }, "clean_cache": { - "title": "Clean Cache", - "message": "Successfully cleaned %s cache." + "title": "Iztīrīt Kešatmiņu", + "message": "%s kešatmiņa ir veiksmīgi iztīrīta." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Piezīme", + "message": "Tulkošana neizdevās. Varbūt administrators nav iespējojis tulkojumus šajā serverī vai arī šajā serverī darbojas vecāka Mastodon versija, kurā tulkojumi vēl netiek atbalstīti.", + "button": "Labi" } }, "controls": { @@ -79,18 +79,18 @@ "take_photo": "Uzņemt bildi", "save_photo": "Saglabāt bildi", "copy_photo": "Kopēt bildi", - "sign_in": "Log in", - "sign_up": "Create account", + "sign_in": "Pieteikties", + "sign_up": "Izveidot kontu", "see_more": "Skatīt vairāk", "preview": "Priekšskatījums", - "copy": "Copy", + "copy": "Kopēt", "share": "Dalīties", - "share_user": "Share %s", - "share_post": "Share Post", + "share_user": "Kopīgot %s", + "share_post": "Kopīgot Ziņu", "open_in_safari": "Atvērt Safari", "open_in_browser": "Atvērt pārlūkprogrammā", "find_people": "Atrodi cilvēkus kam sekot", - "manually_search": "Manually search instead", + "manually_search": "Tā vietā meklēt manuāli", "skip": "Izlaist", "reply": "Atbildēt", "report_user": "Ziņot par lietotāju @%s", @@ -99,33 +99,33 @@ "settings": "Iestatījumi", "delete": "Dzēst", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Tulkot no %s", + "unknown_language": "Nezināms" } }, "tabs": { "home": "Sākums", - "search_and_explore": "Search and Explore", - "notifications": "Notifications", + "search_and_explore": "Meklēt un Pārlūkot", + "notifications": "Paziņojumi", "profile": "Profils" }, "keyboard": { "common": { "switch_to_tab": "Pārslēgties uz: %s", "compose_new_post": "Veidot jaunu ziņu", - "show_favorites": "Show Favorites", + "show_favorites": "Parādīt Izlasi", "open_settings": "Atvērt iestatījumus" }, "timeline": { - "previous_status": "Previous Post", - "next_status": "Next Post", - "open_status": "Open Post", - "open_author_profile": "Open Author's Profile", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", - "toggle_reblog": "Toggle Reblog on Post", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", + "previous_status": "Iepriekšējā Ziņa", + "next_status": "Nākamā Ziņa", + "open_status": "Atvērt Ziņu", + "open_author_profile": "Atvērt Autora Profilu", + "open_reblogger_profile": "Atvērt Pārpublicētāja Profilu", + "reply_status": "Atbildēt uz Ziņu", + "toggle_reblog": "Pārslēgt Atbilde uz Ziņu", + "toggle_favorite": "Pārslēgt Izlasi uz Ziņas", + "toggle_content_warning": "Pārslēgt Satura Brīdinājumu", "preview_image": "Priekšskata attēls" }, "segmented_control": { @@ -134,30 +134,30 @@ } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", - "show_post": "Show Post", + "user_reblogged": "%s pārpublicēja", + "user_replied_to": "Atbildēja %s", + "show_post": "Parādīt Ziņu", "show_user_profile": "Parādīt lietotāja profilu", "content_warning": "Satura brīdinājums", "sensitive_content": "Sensitīvs saturs", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "media_content_warning": "Pieskarieties jebkurā vietā, lai atklātu", + "tap_to_reveal": "Piest, lai atklātu", + "load_embed": "Ielādēt Iegultos", + "link_via_user": "%s caur %s", "poll": { "vote": "Balsot", "closed": "Aizvērts" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Saite: %s", + "hashtag": "Sajaukt: %s", + "mention": "Rādīt Profilu: %s", + "email": "E-pasta adrese: %s" }, "actions": { "reply": "Atbildēt", "reblog": "Reblogot", - "unreblog": "Undo reblog", + "unreblog": "Atsaukt pārpublicēšanu", "favorite": "Izlase", "unfavorite": "Izņemt no izlases", "menu": "Izvēlne", From 9e28d29f7da1264387e18f05a0151bc8a7c2d0e0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 19:42:32 +0100 Subject: [PATCH 609/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 9bb66734d..30f040202 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -467,7 +467,7 @@ "followers": "şopîner" }, "fields": { - "joined": "Joined", + "joined": "Dîroka tevlîbûnê", "add_row": "Rêzê tevlî bike", "placeholder": { "label": "Nîşan", From 390cad1643f3772f14b8797f8aaed78bb806c0c1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 18 Dec 2022 21:57:55 +0100 Subject: [PATCH 610/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index bf912f886..ad0f59a94 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -467,7 +467,7 @@ "followers": "seguidores" }, "fields": { - "joined": "Joined", + "joined": "En este servidor desde", "add_row": "Agregar fila", "placeholder": { "label": "Nombre de campo", From 26e71165a5008c657ca69035f07c12b00d511b34 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 03:21:10 +0100 Subject: [PATCH 611/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index b780c4fff..6d3bd7ca1 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -467,7 +467,7 @@ "followers": "팔로워" }, "fields": { - "joined": "Joined", + "joined": "가입일", "add_row": "행 추가", "placeholder": { "label": "라벨", From 4a3f636c196f6a1d4264daaa4f76c9f3c15f3adf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 05:02:37 +0100 Subject: [PATCH 612/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index bf43a9405..b6712b20c 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -467,7 +467,7 @@ "followers": "pengikut" }, "fields": { - "joined": "Joined", + "joined": "Bergabung", "add_row": "Tambah Baris", "placeholder": { "label": "Label", From 258aea3682aaad00eaeacb434217ebbbdbbb2a9e Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 19 Dec 2022 07:32:48 +0100 Subject: [PATCH 613/733] feat: Show translation provider --- Localization/app.json | 3 ++- .../Provider/DataSourceFacade+Translate.swift | 4 ++-- .../CoreData 7.xcdatamodel/contents | 4 ++-- .../CoreDataStack/Entity/Mastodon/Status.swift | 14 ++++++++++++-- .../Generated/Strings.swift | 8 +++++--- .../Resources/Base.lproj/Localizable.strings | 3 ++- .../Resources/en.lproj/Localizable.strings | 6 ++++-- .../View/Content/StatusView+Configuration.swift | 6 ++++-- .../View/Content/StatusView+ViewModel.swift | 8 ++++++-- .../MastodonUI/View/Content/StatusView.swift | 17 ++++++++++++++--- 10 files changed, 53 insertions(+), 20 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index f884d6004..1292d54d4 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index cd4cec4b0..8ce9c2447 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -39,7 +39,7 @@ extension DataSourceFacade { } private extension DataSourceFacade { - static func translateStatus(provider: Provider, status: Status) async throws -> String? { + static func translateStatus(provider: Provider, status: Status) async throws -> Status.TranslatedContent? { do { let value = try await provider.context .apiService @@ -52,7 +52,7 @@ private extension DataSourceFacade { throw TranslationFailure.emptyOrInvalidResponse } - return content + return Status.TranslatedContent(content: content, provider: value.provider) } catch { throw TranslationFailure.emptyOrInvalidResponse } diff --git a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents index 8fb3edc73..7198c75c6 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents +++ b/MastodonSDK/Sources/CoreDataStack/CoreData.xcdatamodeld/CoreData 7.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -218,7 +218,7 @@ - + diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift index c13b6febb..08f58ca3f 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/Status.swift @@ -11,6 +11,16 @@ import Foundation public final class Status: NSManagedObject { public typealias ID = String + public class TranslatedContent: NSObject { + public let content: String + public let provider: String? + + public init(content: String, provider: String?) { + self.content = content + self.provider = provider + } + } + // sourcery: autoGenerateProperty @NSManaged public private(set) var identifier: ID // sourcery: autoGenerateProperty @@ -103,7 +113,7 @@ public final class Status: NSManagedObject { @NSManaged public private(set) var revealedAt: Date? // sourcery: autoUpdatableObject - @NSManaged public private(set) var translatedContent: String? + @NSManaged public private(set) var translatedContent: TranslatedContent? } extension Status { @@ -504,7 +514,7 @@ extension Status: AutoUpdatableObject { self.revealedAt = revealedAt } } - public func update(translatedContent: String?) { + public func update(translatedContent: TranslatedContent?) { if self.translatedContent != translatedContent { self.translatedContent = translatedContent } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 40d847460..49bf2d7a1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -381,12 +381,14 @@ public enum L10n { public enum Translation { /// Show Original public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Show Original") - /// Translated from %@ - public static func translatedFrom(_ p1: Any) -> String { - return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), fallback: "Translated from %@") + /// Translated from %@ using %@ + public static func translatedFrom(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), String(describing: p2), fallback: "Translated from %@ using %@") } /// Unknown public static let unknownLanguage = L10n.tr("Localizable", "Common.Controls.Status.Translation.UnknownLanguage", fallback: "Unknown") + /// Unknown + public static let unknownProvider = L10n.tr("Localizable", "Common.Controls.Status.Translation.UnknownProvider", fallback: "Unknown") } public enum Visibility { /// Only mentioned user can see this post. diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index a7c26c86e..95534fb6c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -134,8 +134,9 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; "Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; -"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Replied to %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 9afcd60d9..ea106ffd2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -62,8 +62,9 @@ Please check your internet connection."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; -"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@ using %@"; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; +"Common.Controls.Actions.TranslatePost.UnknownProvider" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; "Common.Controls.Friendship.Block" = "Block"; @@ -130,8 +131,9 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; "Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; -"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Replied to %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 42b6f406d..6e950bc95 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -246,13 +246,14 @@ extension StatusView { func revertTranslation() { guard let originalStatus = viewModel.originalStatus else { return } viewModel.translatedFromLanguage = nil + viewModel.translatedUsingProvider = nil originalStatus.reblog?.update(translatedContent: nil) originalStatus.update(translatedContent: nil) configure(status: originalStatus) } func configureTranslated(status: Status) { - let translatedContent: String? = { + let translatedContent: Status.TranslatedContent? = { if let translatedContent = status.reblog?.translatedContent { return translatedContent } @@ -269,10 +270,11 @@ extension StatusView { // content do { - let content = MastodonContent(content: translatedContent, emojis: status.emojis.asDictionary) + let content = MastodonContent(content: translatedContent.content, emojis: status.emojis.asDictionary) let metaContent = try MastodonMetaContent.convert(document: content) viewModel.content = metaContent viewModel.translatedFromLanguage = status.reblog?.language ?? status.language + viewModel.translatedUsingProvider = status.reblog?.translatedContent?.provider ?? status.translatedContent?.provider viewModel.isCurrentlyTranslating = false } catch { assertionFailure(error.localizedDescription) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 5ce4d6ec4..aae8e0b66 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -49,7 +49,8 @@ extension StatusView { // Translation @Published public var isCurrentlyTranslating = false @Published public var translatedFromLanguage: String? - + @Published public var translatedUsingProvider: String? + @Published public var timestamp: Date? public var timestampFormatter: ((_ date: Date) -> String)? @Published public var timestampText = "" @@ -145,6 +146,7 @@ extension StatusView { isMediaSensitive = false isSensitiveToggled = false translatedFromLanguage = nil + translatedUsingProvider = nil isCurrentlyTranslating = false activeFilters = [] @@ -629,7 +631,9 @@ extension StatusView.ViewModel { guard let context = self.context, let authContext = self.authContext - else { return nil } + else { + return nil + } var configuration: Mastodon.Entity.V2.Instance.Configuration? = nil context.managedObjectContext.performAndWait { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index e73d00342..dcacd7a06 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -191,6 +191,7 @@ public final class StatusView: UIView { let label = UILabel() label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) label.textColor = Asset.Colors.Label.secondary.color + label.numberOfLines = 2 return label }() lazy var translatedInfoView: UIView = { @@ -212,10 +213,14 @@ public final class StatusView: UIView { containerView.addSubview($0) } + translatedInfoLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + revertButton.setContentHuggingPriority(.required, for: .horizontal) + NSLayoutConstraint.activate([ containerView.heightAnchor.constraint(equalToConstant: 24), translatedInfoLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), translatedInfoLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16), + translatedInfoLabel.trailingAnchor.constraint(equalTo: revertButton.leadingAnchor, constant: -16), revertButton.topAnchor.constraint(equalTo: containerView.topAnchor), revertButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16), revertButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) @@ -735,12 +740,18 @@ extension StatusView { } .store(in: &disposeBag) - viewModel.$translatedFromLanguage + Publishers.CombineLatest( + viewModel.$translatedFromLanguage, + viewModel.$translatedUsingProvider + ) .receive(on: DispatchQueue.main) - .sink { [weak self] translatedFromLanguage in + .sink { [weak self] translatedFromLanguage, translatedUsingProvider in guard let self = self else { return } if let translatedFromLanguage = translatedFromLanguage { - self.translatedInfoLabel.text = L10n.Common.Controls.Status.Translation.translatedFrom(Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? L10n.Common.Controls.Status.Translation.unknownLanguage) + self.translatedInfoLabel.text = L10n.Common.Controls.Status.Translation.translatedFrom( + Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? L10n.Common.Controls.Status.Translation.unknownLanguage, + translatedUsingProvider ?? L10n.Common.Controls.Status.Translation.unknownProvider + ) self.translatedInfoView.isHidden = false } else { self.translatedInfoView.isHidden = true From ec80ad39ef84505bf4ae412e1779451b5ea09e6c Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 19 Dec 2022 07:33:20 +0100 Subject: [PATCH 614/733] fix: Translation not available in threads --- Mastodon/Diffable/Status/StatusSection.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Mastodon/Diffable/Status/StatusSection.swift b/Mastodon/Diffable/Status/StatusSection.swift index 8ccb32c0c..9b45bae62 100644 --- a/Mastodon/Diffable/Status/StatusSection.swift +++ b/Mastodon/Diffable/Status/StatusSection.swift @@ -279,6 +279,7 @@ extension StatusSection { statusView: cell.statusView ) + cell.statusView.viewModel.context = configuration.context cell.statusView.viewModel.authContext = configuration.authContext cell.configure( From 7921c43d5c4d9ac088d44ad2e90223cafd782ca7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 08:35:27 +0100 Subject: [PATCH 615/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 5e772d6c6..edfc43b7e 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -467,7 +467,7 @@ "followers": "seguidoras" }, "fields": { - "joined": "Joined", + "joined": "Uniuse", "add_row": "Engadir fila", "placeholder": { "label": "Etiqueta", From 4cb84fa55458cfce86d5cff1be5bd5dbd0339cdd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 10:06:46 +0100 Subject: [PATCH 616/733] New translations app.json (Icelandic) --- .../StringsConvertor/input/is.lproj/app.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 8437a68ba..0cdbfa992 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -53,9 +53,9 @@ "message": "Tókst að hreinsa %s skyndiminni." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Athugasemd", + "message": "Þýðing mistókst. Mögulega hefur kerfisstjórinn ekki virkjað þýðingar á þessum netþjóni, eða að netþjónninn sé keyrður á eldri útgáfu Mastodon þar sem þýðingar séu ekki studdar.", + "button": "Í lagi" } }, "controls": { @@ -83,7 +83,7 @@ "sign_up": "Stofna notandaaðgang", "see_more": "Sjá fleira", "preview": "Forskoða", - "copy": "Copy", + "copy": "Afrita", "share": "Deila", "share_user": "Deila %s", "share_post": "Deila færslu", @@ -99,8 +99,8 @@ "settings": "Stillingar", "delete": "Eyða", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Þýða úr %s", + "unknown_language": "Óþekkt" } }, "tabs": { @@ -143,7 +143,7 @@ "media_content_warning": "Ýttu hvar sem er til að birta", "tap_to_reveal": "Ýttu til að birta", "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "link_via_user": "%s með %s", "poll": { "vote": "Greiða atkvæði", "closed": "Lokið" @@ -165,7 +165,7 @@ "show_image": "Sýna mynd", "show_gif": "Birta GIF-myndir", "show_video_player": "Sýna myndspilara", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Deila tengli í færslu", "tap_then_hold_to_show_menu": "Ýttu og haltu til að sýna valmynd" }, "tag": { @@ -183,9 +183,9 @@ "direct": "Einungis notendur sem minnst er á geta séð þessa færslu." }, "translation": { - "translated_from": "Translated from %s", - "unknown_language": "Unknown", - "show_original": "Shown Original" + "translated_from": "Þýtt úr %s", + "unknown_language": "Óþekkt", + "show_original": "Birta upprunalegt" } }, "friendship": { @@ -467,7 +467,7 @@ "followers": "fylgjendur" }, "fields": { - "joined": "Joined", + "joined": "Gerðist þátttakandi", "add_row": "Bæta við röð", "placeholder": { "label": "Skýring", From 98154ec2c3376b2264ae3031e6157f28a71d5c60 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 19 Dec 2022 11:01:13 +0100 Subject: [PATCH 617/733] chore: Don't limit number of lines on translation info text --- MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index dcacd7a06..f64b0b225 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -191,7 +191,7 @@ public final class StatusView: UIView { let label = UILabel() label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) label.textColor = Asset.Colors.Label.secondary.color - label.numberOfLines = 2 + label.numberOfLines = 0 return label }() lazy var translatedInfoView: UIView = { From bff0131ea84a404368d38ffd5105baec6676f65c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:43 +0100 Subject: [PATCH 618/733] New translations app.json (French) --- Localization/StringsConvertor/input/fr.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 59be72b68..1186e0549 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Seul·e l’utilisateur·rice mentionnée peut voir ce message." }, "translation": { - "translated_from": "Traduit depuis %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Inconnu", + "unknown_provider": "Unknown", "show_original": "Afficher l’original" } }, From bb24aaca0e3fc9c7d64d3c809cf3ea2121ed4091 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:44 +0100 Subject: [PATCH 619/733] New translations app.json (Romanian) --- Localization/StringsConvertor/input/ro.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index de8a2c00a..a17e3b1e8 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 7f030ca0a27ca4620d37e0414d582d15485a2bff Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:45 +0100 Subject: [PATCH 620/733] New translations app.json (Slovenian) --- Localization/StringsConvertor/input/sl.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index b9f954047..92013ea33 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Samo omenjeni uporabnik lahko vidi to objavo." }, "translation": { - "translated_from": "Prevedeno iz jezika: %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Neznano", + "unknown_provider": "Unknown", "show_original": "Pokaži izvirnik" } }, From a1d2ee422a8a3b1326ca3953c504c9f4c09f4e52 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:46 +0100 Subject: [PATCH 621/733] New translations app.json (Chinese Traditional) --- Localization/StringsConvertor/input/zh-Hant.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index b07fc0a7b..b94e42bc6 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -183,8 +183,9 @@ "direct": "只有被提及的使用者能看到此嘟文。" }, "translation": { - "translated_from": "翻譯自 %s", + "translated_from": "Translated from %s using %s", "unknown_language": "未知", + "unknown_provider": "Unknown", "show_original": "顯示原文" } }, From dd104e0c52ac91b084858aaa838574c1341ebab0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:47 +0100 Subject: [PATCH 622/733] New translations app.json (Vietnamese) --- Localization/StringsConvertor/input/vi.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index c0b04c897..37c30ca20 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Chỉ người được nhắc đến có thể thấy tút." }, "translation": { - "translated_from": "Dịch từ %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Không xác định", + "unknown_provider": "Unknown", "show_original": "Bản gốc" } }, From 302ccd9dc8b026fc2cdee0770a44de709f7ac770 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:48 +0100 Subject: [PATCH 623/733] New translations app.json (Kabyle) --- Localization/StringsConvertor/input/kab.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index fcb8151f9..581b0f55a 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -183,8 +183,9 @@ "direct": "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 5167e5f5a79f390fe4aa97059387c07d854fb9e3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:50 +0100 Subject: [PATCH 624/733] New translations app.json (Korean) --- Localization/StringsConvertor/input/ko.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 6d3bd7ca1..815af4cbb 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "%s에서 번역됨", + "translated_from": "Translated from %s using %s", "unknown_language": "알 수 없음", + "unknown_provider": "Unknown", "show_original": "원본 보기" } }, From f788bf7465d1db6748aafb1791405c3ca365d28f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:51 +0100 Subject: [PATCH 625/733] New translations app.json (Swedish) --- Localization/StringsConvertor/input/sv.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index cd8320db5..aaf76d01b 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Endast omnämnda användare kan se detta inlägg." }, "translation": { - "translated_from": "Översatt från %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Okänt", + "unknown_provider": "Unknown", "show_original": "Visa original" } }, From 9189c3d593a05d130526b003b07a030667a6fb92 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:52 +0100 Subject: [PATCH 626/733] New translations app.json (Turkish) --- Localization/StringsConvertor/input/tr.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 640aa35c0..fe7e63984 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Sadece bahsedilen kullanıcı bu gönderiyi görebilir." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 1d562cbeada79dc7be38d6ffb1d3ce3f45dbc13b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:53 +0100 Subject: [PATCH 627/733] New translations app.json (Czech) --- Localization/StringsConvertor/input/cs.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 974ac12dc..0c210fa37 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Pouze zmíněný uživatel může vidět tento příspěvek." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From f3dc4edd8750fee69cdf0c20b10be205ad1cda40 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:55 +0100 Subject: [PATCH 628/733] New translations app.json (Ukrainian) --- Localization/StringsConvertor/input/uk.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 6b4f8f75c..25c28e5d7 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Тільки згаданий користувач може бачити цю публікацію." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 70fd21c156997249fcf07e9ab8528513dfc55cb3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:56 +0100 Subject: [PATCH 629/733] New translations app.json (Scottish Gaelic) --- Localization/StringsConvertor/input/gd.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 659572e8f..5cea86c4b 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Chan fhaic ach an cleachdaiche air an dugadh iomradh am post seo." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From d946fc5535a2a7a103bba129b6fd03198199a95d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:57 +0100 Subject: [PATCH 630/733] New translations app.json (Spanish) --- Localization/StringsConvertor/input/es.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 205a0c4df..894e752a6 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Traducido de %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Desconocido", + "unknown_provider": "Unknown", "show_original": "Mostrar Original" } }, From f5030eb5816760fb1f11f97bf59faf025daeb572 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:58 +0100 Subject: [PATCH 631/733] New translations app.json (Arabic) --- Localization/StringsConvertor/input/ar.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 42d3bfc5d..e752a79e5 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -183,8 +183,9 @@ "direct": "المُستخدمِونَ المُشارِ إليهم فَقَطْ مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From c36cb141674246e0745dd7699772fa47492b5f66 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:24:59 +0100 Subject: [PATCH 632/733] New translations app.json (Catalan) --- Localization/StringsConvertor/input/ca.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index a30726151..81b9c49db 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Només l'usuari mencionat pot veure aquesta publicació." }, "translation": { - "translated_from": "Traduït des d'el %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Desconegut", + "unknown_provider": "Unknown", "show_original": "Mostra l'original" } }, From 3d47f876e5d09ebdefb422e0f5fd046f8a6ac870 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:00 +0100 Subject: [PATCH 633/733] New translations app.json (Danish) --- Localization/StringsConvertor/input/da.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 52f1fa405..8114a1bf4 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 7b01ee8944debd6510be393cc877c542cbb7b43f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:01 +0100 Subject: [PATCH 634/733] New translations app.json (German) --- Localization/StringsConvertor/input/de.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 73d9e5605..b50556f53 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Nur erwähnte Benutzer können diesen Beitrag sehen." }, "translation": { - "translated_from": "Übersetzt von %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unbekannt", + "unknown_provider": "Unknown", "show_original": "Original anzeigen" } }, From 37ccd6b3375bd34b5b73d96154e9ff170c9464ee Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:02 +0100 Subject: [PATCH 635/733] New translations app.json (Basque) --- Localization/StringsConvertor/input/eu.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index c07692277..f6ec71d44 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Aipatutako erabiltzaileek soilik ikus dezakete bidalketa hau." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 6f31c34010957143aafd049c3419b2307a7b16a1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:03 +0100 Subject: [PATCH 636/733] New translations app.json (Finnish) --- Localization/StringsConvertor/input/fi.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 721c25636..9bdd23991 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From e28d3c00d01ec376f73878bce64e68187ae3b35c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:04 +0100 Subject: [PATCH 637/733] New translations app.json (Italian) --- Localization/StringsConvertor/input/it.lproj/app.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index d86287025..9eaae69d3 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Solo l'utente menzionato può vedere questo post." }, "translation": { - "translated_from": "Tradotto da %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Sconosciuto", + "unknown_provider": "Unknown", "show_original": "Mostra l'originale" } }, @@ -467,7 +468,7 @@ "followers": "seguaci" }, "fields": { - "joined": "Joined", + "joined": "Profilo iscritto", "add_row": "Aggiungi riga", "placeholder": { "label": "Etichetta", From 2fb57105a5b395e81b4666c16dbef0fd5c5aa4d0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:05 +0100 Subject: [PATCH 638/733] New translations app.json (Japanese) --- Localization/StringsConvertor/input/ja.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index c716b18ff..92440f927 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -183,8 +183,9 @@ "direct": "この投稿はメンションされたユーザーに限り見ることができます。" }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 998d1c3deecabc1dded186a64a76954f34d7a69d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:06 +0100 Subject: [PATCH 639/733] New translations app.json (Dutch) --- Localization/StringsConvertor/input/nl.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 30ed3b56a..740e4f211 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Alleen de vermelde persoon kan dit bericht zien." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From d2a72aea2c532cbc96b9b43811b397c97c082f64 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:07 +0100 Subject: [PATCH 640/733] New translations app.json (Portuguese) --- Localization/StringsConvertor/input/pt.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 52f1fa405..8114a1bf4 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From ecefb6d1427583558287d5b599a26da4f18c41e7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:08 +0100 Subject: [PATCH 641/733] New translations app.json (Russian) --- Localization/StringsConvertor/input/ru.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 588e70d1e..ac8b73246 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From dd3009110e66e4037cee8d528dcc798f4b8201e6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:09 +0100 Subject: [PATCH 642/733] New translations app.json (Chinese Simplified) --- Localization/StringsConvertor/input/zh-Hans.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 6329a7990..a7dae16b2 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -183,8 +183,9 @@ "direct": "只有提到的用户才能看到此帖子。" }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From fc2ae7eb210ec218721483c9a05e80438c785e67 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:10 +0100 Subject: [PATCH 643/733] New translations app.json (English) --- Localization/StringsConvertor/input/en.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 402ffc117..b28aac1c7 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From f15faf08b3d59834daf7e1786cb54618c02a4b69 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:11 +0100 Subject: [PATCH 644/733] New translations app.json (Galician) --- Localization/StringsConvertor/input/gl.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index edfc43b7e..d3ded8866 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Só a usuaria mencionada pode ver a publicación." }, "translation": { - "translated_from": "Traducido do %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Descoñecido", + "unknown_provider": "Unknown", "show_original": "Mostrar o orixinal" } }, From c9216892883506ac3b23fea0a6e61c9921815ec0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:13 +0100 Subject: [PATCH 645/733] New translations app.json (Portuguese, Brazilian) --- Localization/StringsConvertor/input/pt-BR.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 1eb88370e..7c0128f39 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Somente o usuário mencionado pode ver essa postagem." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 3b9179ae10b3b64fbf2f0c8db2a2db5f0a9c80db Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:14 +0100 Subject: [PATCH 646/733] New translations app.json (Indonesian) --- Localization/StringsConvertor/input/id.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index b6712b20c..be121bb00 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Hanya pengguna yang disebut yang dapat melihat postingan ini." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 8f5d96b73774597710de7e93be68e4b52a775eab Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:15 +0100 Subject: [PATCH 647/733] New translations app.json (Spanish, Argentina) --- Localization/StringsConvertor/input/es-AR.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index ad0f59a94..a494b2854 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Traducido desde el %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Desconocido", + "unknown_provider": "Unknown", "show_original": "Mostrar original" } }, From 57b78fd469ce7c2682bc606620b75e6a8a6235bf Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:16 +0100 Subject: [PATCH 648/733] New translations app.json (Thai) --- Localization/StringsConvertor/input/th.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 7ce8df356..32e79f756 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -183,8 +183,9 @@ "direct": "เฉพาะผู้ใช้ที่กล่าวถึงเท่านั้นที่สามารถเห็นโพสต์นี้" }, "translation": { - "translated_from": "แปลจาก %s", + "translated_from": "Translated from %s using %s", "unknown_language": "ไม่รู้จัก", + "unknown_provider": "Unknown", "show_original": "แสดงดั้งเดิมอยู่" } }, From c9b05715e6851eb2dadf76c43a3fa36b8e40d810 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:17 +0100 Subject: [PATCH 649/733] New translations app.json (Latvian) --- Localization/StringsConvertor/input/lv.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 9b1a8c074..5a8cc6df6 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From b43727ac8aefbdce435c52c4d98b63782c502c93 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:18 +0100 Subject: [PATCH 650/733] New translations app.json (Hindi) --- Localization/StringsConvertor/input/hi.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index a51761eeb..2b620f0a9 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From d5c86c08adf8ce7215c5e74c72a717c48083853f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:19 +0100 Subject: [PATCH 651/733] New translations app.json (English, United States) --- Localization/StringsConvertor/input/en-US.lproj/app.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 52f1fa405..b28aac1c7 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, @@ -378,7 +379,7 @@ "published": "Published!", "Publishing": "Publishing post...", "accessibility": { - "logo_label": "Logo Button", + "logo_label": "Mastodon", "logo_hint": "Tap to scroll to top and tap again to previous location" } } @@ -467,7 +468,7 @@ "followers": "followers" }, "fields": { - "joined": "Joined", + "joined": "Liitytty", "add_row": "Add Row", "placeholder": { "label": "Label", From a646df9ebab383205c077bebfc5f9d11cc77f4ce Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:20 +0100 Subject: [PATCH 652/733] New translations app.json (Welsh) --- Localization/StringsConvertor/input/cy.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index e6a0d40ee..0838ef9ff 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Dim ond y ddefnyddiwr â soniwyd sy'n gallu gweld y post hwn." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 7596ee78be660393a6d576fa2b2e3a1c52ab0bf0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:21 +0100 Subject: [PATCH 653/733] New translations app.json (Sinhala) --- Localization/StringsConvertor/input/si.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 9d377d5d2..cdeec5d49 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From f12c1382f8e74d7890966eeef74a4302994f99be Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:22 +0100 Subject: [PATCH 654/733] New translations app.json (Kurmanji (Kurdish)) --- Localization/StringsConvertor/input/kmr.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 30f040202..c1a4fdfdd 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Tenê bikarhênerê qalkirî dikare vê şandiyê bibîne." }, "translation": { - "translated_from": "Ji %s hate wergerandin", + "translated_from": "Translated from %s using %s", "unknown_language": "Nenas", + "unknown_provider": "Unknown", "show_original": "A resen nîşan bide" } }, From 41e751f8505f136dd5ea3e6b5bd28ab88d41493a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:23 +0100 Subject: [PATCH 655/733] New translations app.json (Sorani (Kurdish)) --- Localization/StringsConvertor/input/ckb.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index b04834856..693c8e9f6 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -183,8 +183,9 @@ "direct": "تەنیا بەکارهێنەرە ئاماژە پێکراوەکە دەتوانێت ئەم پۆستە ببینێت." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From a5ad32fd2ca9dba19db4c5762fd6b64943c4f68a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:24 +0100 Subject: [PATCH 656/733] New translations app.json (Icelandic) --- Localization/StringsConvertor/input/is.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 0cdbfa992..29e4f45aa 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Einungis notendur sem minnst er á geta séð þessa færslu." }, "translation": { - "translated_from": "Þýtt úr %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Óþekkt", + "unknown_provider": "Unknown", "show_original": "Birta upprunalegt" } }, From 06fb253e8adf5e94cec4845779a6b0811ecb34a3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:26 +0100 Subject: [PATCH 657/733] New translations app.json (Burmese) --- Localization/StringsConvertor/input/my.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index e5ed501c5..2b86c884a 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -183,8 +183,9 @@ "direct": "ရည်ညွှန်းခံရသောအသုံးပြုသူများသာ ဒီပို့စ်ကို မြင်နိုင်သည်" }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From eb56916717df5590fd9770af37a5f4d1b994551c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:27 +0100 Subject: [PATCH 658/733] New translations app.json (Aragonese) --- Localization/StringsConvertor/input/an.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 09d251137..84463895e 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Nomás l'usuario mencionau puede veyer este mensache." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 1373cc73d93573c88397a0c2a4bfdfa8d6075128 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 19 Dec 2022 11:25:28 +0100 Subject: [PATCH 659/733] New translations app.json (Hebrew) --- Localization/StringsConvertor/input/he.lproj/app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index b2d679b61..4d0bdbd5f 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -183,8 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s", + "translated_from": "Translated from %s using %s", "unknown_language": "Unknown", + "unknown_provider": "Unknown", "show_original": "Shown Original" } }, From 3e34b34fe78aa1c76a2c9e88efee86526c93b2f3 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 19 Dec 2022 12:06:46 +0100 Subject: [PATCH 660/733] Fix typo --- Localization/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/README.md b/Localization/README.md index 93bf290bc..b44fa350d 100644 --- a/Localization/README.md +++ b/Localization/README.md @@ -27,7 +27,7 @@ If there are new translations, Crowdin pushes new commits to a branch called `l1 To update or add new translations, the workflow is as follows: 1. Merge the PR with `l10n_develop` into `develop`. It's usually called `New Crowdin Updates` -2. Run `update.localization.sh` on your computer. +2. Run `update_localization.sh` on your computer. 3. Commit the changes and push `develop`. [crowdin-mastodon-ios]: https://crowdin.com/project/mastodon-for-ios From f3d71d982a9663dfdc93ccc5332e97dc9bddc75d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 19 Dec 2022 12:07:16 +0100 Subject: [PATCH 661/733] Update strings --- .../input/Base.lproj/app.json | 17 +- MastodonIntent/ca.lproj/Intents.strings | 6 +- MastodonIntent/de.lproj/Intents.strings | 8 +- .../Generated/Strings.swift | 4 +- .../Resources/Base.lproj/Localizable.strings | 8 +- .../Resources/ar.lproj/Localizable.strings | 38 +++- .../ar.lproj/Localizable.stringsdict | 6 +- .../Resources/ca.lproj/Localizable.strings | 176 ++++++++++-------- .../ca.lproj/Localizable.stringsdict | 12 +- .../Resources/ckb.lproj/Localizable.strings | 24 ++- .../Resources/cs.lproj/Localizable.strings | 26 ++- .../Resources/de.lproj/Localizable.strings | 86 +++++---- .../de.lproj/Localizable.stringsdict | 8 +- .../Resources/en.lproj/Localizable.strings | 28 ++- .../en.lproj/Localizable.stringsdict | 8 +- .../Resources/es.lproj/Localizable.strings | 84 +++++---- .../es.lproj/Localizable.stringsdict | 6 +- .../Resources/eu.lproj/Localizable.strings | 150 ++++++++------- .../eu.lproj/Localizable.stringsdict | 4 +- .../Resources/fi.lproj/Localizable.strings | 24 ++- .../Resources/fr.lproj/Localizable.strings | 24 ++- .../Resources/gd.lproj/Localizable.strings | 24 ++- .../Resources/gl.lproj/Localizable.strings | 24 ++- .../Resources/it.lproj/Localizable.strings | 26 ++- .../Resources/ja.lproj/Localizable.strings | 94 ++++++---- .../Resources/kab.lproj/Localizable.strings | 24 ++- .../Resources/ku.lproj/Localizable.strings | 24 ++- .../Resources/nl.lproj/Localizable.strings | 116 +++++++----- .../nl.lproj/Localizable.stringsdict | 2 +- .../Resources/ru.lproj/Localizable.strings | 24 ++- .../ru.lproj/Localizable.stringsdict | 6 +- .../Resources/sl.lproj/Localizable.strings | 24 ++- .../Resources/sv.lproj/Localizable.strings | 24 ++- .../sv.lproj/Localizable.stringsdict | 12 +- .../Resources/th.lproj/Localizable.strings | 24 ++- .../Resources/tr.lproj/Localizable.strings | 108 ++++++----- .../tr.lproj/Localizable.stringsdict | 14 +- .../Resources/vi.lproj/Localizable.strings | 26 ++- .../zh-Hans.lproj/Localizable.strings | 24 ++- .../zh-Hant.lproj/Localizable.strings | 24 ++- 40 files changed, 945 insertions(+), 446 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index f09837498..1292d54d4 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -51,6 +51,11 @@ "clean_cache": { "title": "Clean Cache", "message": "Successfully cleaned %s cache." + }, + "translation_failed": { + "title": "Note", + "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "button": "OK" } }, "controls": { @@ -92,7 +97,11 @@ "block_domain": "Block %s", "unblock_domain": "Unblock %s", "settings": "Settings", - "delete": "Delete" + "delete": "Delete", + "translate_post": { + "title": "Translate from %s", + "unknown_language": "Unknown" + } }, "tabs": { "home": "Home", @@ -172,6 +181,12 @@ "private": "Only their followers can see this post.", "private_from_me": "Only my followers can see this post.", "direct": "Only mentioned user can see this post." + }, + "translation": { + "translated_from": "Translated from %s using %s", + "unknown_language": "Unknown", + "unknown_provider": "Unknown", + "show_original": "Shown Original" } }, "friendship": { diff --git a/MastodonIntent/ca.lproj/Intents.strings b/MastodonIntent/ca.lproj/Intents.strings index 6b92eb263..c02ac08cf 100644 --- a/MastodonIntent/ca.lproj/Intents.strings +++ b/MastodonIntent/ca.lproj/Intents.strings @@ -22,7 +22,7 @@ "ZbSjzC" = "Visibilitat"; -"Zo4jgJ" = "Visibilitat de la Publicació"; +"Zo4jgJ" = "Visibilitat de la publicació"; "apSxMG-dYQ5NN" = "Hi ha ${count} opcions que coincideixen amb ‘Públic’."; @@ -30,9 +30,9 @@ "ayoYEb-dYQ5NN" = "${content}, Públic"; -"ayoYEb-ehFLjY" = "${content}, Només Seguidors"; +"ayoYEb-ehFLjY" = "${content}, Només seguidors"; -"dUyuGg" = "Publicació"; +"dUyuGg" = "Publica a Mastodon"; "dYQ5NN" = "Públic"; diff --git a/MastodonIntent/de.lproj/Intents.strings b/MastodonIntent/de.lproj/Intents.strings index fd3fbd40f..5d0056766 100644 --- a/MastodonIntent/de.lproj/Intents.strings +++ b/MastodonIntent/de.lproj/Intents.strings @@ -1,12 +1,12 @@ -"16wxgf" = "Auf Mastodon posten"; +"16wxgf" = "Auf Mastodon veröffentlichen"; "751xkl" = "Textinhalt"; -"CsR7G2" = "Auf Mastodon posten"; +"CsR7G2" = "Auf Mastodon veröffentlichen"; -"HZSGTr" = "Welcher Inhalt soll gepostet werden?"; +"HZSGTr" = "Welcher Inhalt soll veröffentlicht werden?"; -"HdGikU" = "Posten fehlgeschlagen"; +"HdGikU" = "Veröffentlichen fehlgeschlagen"; "KDNTJ4" = "Fehlerursache"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 49bf2d7a1..22b858578 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -379,8 +379,8 @@ public enum L10n { public static let url = L10n.tr("Localizable", "Common.Controls.Status.Tag.Url", fallback: "URL") } public enum Translation { - /// Show Original - public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Show Original") + /// Shown Original + public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Shown Original") /// Translated from %@ using %@ public static func translatedFrom(_ p1: Any, _ p2: Any) -> String { return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), String(describing: p2), fallback: "Translated from %@ using %@") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 95534fb6c..bf17df206 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -22,9 +22,9 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; -"Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; @@ -133,7 +133,7 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; "Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; @@ -481,4 +481,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index 17d0569c7..8ecefd32e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "هل أنت متأكد من رغبتك في تسجيل الخُروج؟"; "Common.Alerts.SignOut.Title" = "تَسجيلُ الخُروج"; "Common.Alerts.SignUpFailure.Title" = "إخفاقٌ فِي التَّسجيل"; +"Common.Alerts.TranslationFailed.Button" = "حسنًا"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "مُلاحظة"; "Common.Alerts.VoteFailure.PollEnded" = "اِنتَهَى اِستِطلاعُ الرَّأي"; "Common.Alerts.VoteFailure.Title" = "إخفاقٌ فِي التَّصويت"; "Common.Controls.Actions.Add" = "إضافة"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "تأليف"; "Common.Controls.Actions.Confirm" = "تأكيد"; "Common.Controls.Actions.Continue" = "واصل"; +"Common.Controls.Actions.Copy" = "نَسخ"; "Common.Controls.Actions.CopyPhoto" = "نسخ الصورة"; "Common.Controls.Actions.Delete" = "حذف"; "Common.Controls.Actions.Discard" = "تجاهُل"; @@ -56,9 +60,11 @@ "Common.Controls.Actions.SharePost" = "مشارك المنشور"; "Common.Controls.Actions.ShareUser" = "مُشارَكَةُ %@"; "Common.Controls.Actions.SignIn" = "تسجيلُ الدخول"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignUp" = "إنشاءُ حِساب"; "Common.Controls.Actions.Skip" = "تخطي"; "Common.Controls.Actions.TakePhoto" = "اِلتِقاطُ صُورَة"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "المُحاولة مرة أُخرى"; "Common.Controls.Actions.UnblockDomain" = "رفع الحظر عن %@"; "Common.Controls.Friendship.Block" = "حظر"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "القائمة"; "Common.Controls.Status.Actions.Reblog" = "إعادة النشر"; "Common.Controls.Status.Actions.Reply" = "الرَّد"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "أظْهِر GIF"; "Common.Controls.Status.Actions.ShowImage" = "أظْهِرِ الصُّورَة"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "أظْهِر مُشَغِّلَ المَقاطِعِ المَرئِيَّة"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "إزالة التفضيل"; "Common.Controls.Status.Actions.Unreblog" = "التراجُع عن إعادة النشر"; "Common.Controls.Status.ContentWarning" = "تحذير المُحتوى"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "اُنقُر لِلكَشف"; "Common.Controls.Status.MetaEntity.Email" = "عُنوان البريد الإلكتُروني: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "وَسْم: %@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "إشارة"; "Common.Controls.Status.Tag.Url" = "عنوان URL"; "Common.Controls.Status.TapToReveal" = "اُنقُر لِلكَشف"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "أعادَ %@ تَدوينَها"; "Common.Controls.Status.UserRepliedTo" = "رَدًا على %@"; "Common.Controls.Status.Visibility.Direct" = "المُستخدمِونَ المُشارِ إليهم فَقَطْ مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور."; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "فَقَطْ مُتابِعيني أنَا مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور."; "Common.Controls.Status.Visibility.Unlisted" = "يُمكِنُ لِلجَميعِ رُؤيَةُ هَذَا المَنشورِ وَلكِنَّهُ لَا يُعرَضُ فِي الخَطِّ الزَمنيّ العام."; "Common.Controls.Tabs.Home" = "الرَّئِيسَة"; -"Common.Controls.Tabs.Notification" = "الإشعارات"; +"Common.Controls.Tabs.Notifications" = "الإشعارات"; "Common.Controls.Tabs.Profile" = "المِلَفُّ التَّعريفِيّ"; -"Common.Controls.Tabs.Search" = "البَحث"; +"Common.Controls.Tabs.SearchAndExplore" = "البَحث وَالاِستِكشاف"; "Common.Controls.Timeline.Filtered" = "مُصفَّى"; "Common.Controls.Timeline.Header.BlockedWarning" = "لا يُمكِنُكَ عَرض الملف التَعريفي لهذا المُستخدِم حتَّى يَرفَعَ الحَظرَ عَنك."; @@ -161,7 +174,7 @@ "Scene.Compose.Accessibility.CustomEmojiPicker" = "منتقي الرموز التعبيرية المُخصَّص"; "Scene.Compose.Accessibility.DisableContentWarning" = "تعطيل تحذير المُحتَوى"; "Scene.Compose.Accessibility.EnableContentWarning" = "تفعيل تحذير المُحتَوى"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "خياراتُ المَنشور"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "قائمة ظهور المنشور"; "Scene.Compose.Accessibility.PostingAs" = "نَشر كَـ %@"; "Scene.Compose.Accessibility.RemovePoll" = "إزالة الاستطلاع"; @@ -229,6 +242,12 @@ "Scene.Familiarfollowers.Title" = "مُتابِعُونَ مَألُوفُونَ بِالنِّسبَةِ لَك"; "Scene.Favorite.Title" = "مُفضَّلَتُك"; "Scene.FavoritedBy.Title" = "مُفَضَّلٌ مِن قِبَلِ"; +"Scene.FollowedTags.Actions.Follow" = "مُتابَعَة"; +"Scene.FollowedTags.Actions.Unfollow" = "إلغاءُ المُتابَعَة"; +"Scene.FollowedTags.Header.Participants" = "المُشارِكُون"; +"Scene.FollowedTags.Header.Posts" = "مَنشورات"; +"Scene.FollowedTags.Header.PostsToday" = "مَنشوراتُ اليَوم"; +"Scene.FollowedTags.Title" = "وُسُومُ المُتابَع"; "Scene.Follower.Footer" = "لا يُمكِن عَرض المُتابِعين مِنَ الخوادم الأُخرى."; "Scene.Follower.Title" = "مُتابِعِين"; "Scene.Following.Footer" = "لا يُمكِن عَرض المُتابَعات مِنَ الخوادم الأُخرى."; @@ -240,9 +259,9 @@ "Scene.HomeTimeline.NavigationBarState.Published" = "تمَّ النَّشر!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "يَجري نَشر المُشارَكَة..."; "Scene.HomeTimeline.Title" = "الرَّئِيسَة"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; +"Scene.Login.ServerSearchField.Placeholder" = "أدخِل عُنوانَ URL أو اِبحَث عَنِ الخادِمِ الخاصّ بِك"; +"Scene.Login.Subtitle" = "سَجِّل دُخولَكَ إلى الخادِم الَّذي أنشأتَ حِسابَكَ فيه."; +"Scene.Login.Title" = "مَرحَبًا بِكَ مُجَدَّدًا"; "Scene.Notification.FollowRequest.Accept" = "قَبُول"; "Scene.Notification.FollowRequest.Accepted" = "مَقبُول"; "Scene.Notification.FollowRequest.Reject" = "رَفض"; @@ -268,6 +287,7 @@ "Scene.Profile.Dashboard.Following" = "مُتابَع"; "Scene.Profile.Dashboard.Posts" = "مَنشورات"; "Scene.Profile.Fields.AddRow" = "إضافة صف"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "المُحتَوى"; "Scene.Profile.Fields.Placeholder.Label" = "التسمية"; "Scene.Profile.Fields.Verified.Long" = "تمَّ التَّحقق مِن مِلكية هذا الرابِطِ بِتاريخ %@"; @@ -404,11 +424,11 @@ "Scene.ServerPicker.EmptyState.BadNetwork" = "حدث خطأٌ ما أثناء تحميل البيانات. تحقَّق من اتصالك بالإنترنت."; "Scene.ServerPicker.EmptyState.FindingServers" = "يجري إيجاد خوادم متوفِّرَة..."; "Scene.ServerPicker.EmptyState.NoResults" = "لا توجد نتائج"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "اِبحث عَن مُجتَمَعَات أو أدخِل عُنوانَ URL"; "Scene.ServerPicker.Label.Category" = "الفئة"; "Scene.ServerPicker.Label.Language" = "اللُّغَة"; "Scene.ServerPicker.Label.Users" = "مُستَخدِم"; -"Scene.ServerPicker.Subtitle" = "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers."; +"Scene.ServerPicker.Subtitle" = "اِختر خادمًا بناءً على منطقتك، اِهتماماتك أو يُمكنك حتى اِختيارُ مجتمعٍ ذِي غرضٍ عام. بِإمكانِكَ الدردشة مع أي شخص على مَاستودُون، بغض النظر عن الخادم الخاصة بك."; "Scene.ServerPicker.Title" = "اِختر خادِم، أيًّا مِنهُم."; "Scene.ServerRules.Button.Confirm" = "أنا مُوافِق"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict index 91368a4fb..35727c0d6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict @@ -77,7 +77,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + يتبقى %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -91,9 +91,9 @@ two حَرفانِ اِثنان few - %ld characters + %ld أحرُف many - %ld characters + %ld حَرفًا other %ld حَرف diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index 43c63deda..acd53cc03 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -1,36 +1,40 @@ -"Common.Alerts.BlockDomain.BlockEntireDomain" = "Bloquejar Domini"; -"Common.Alerts.BlockDomain.Title" = "Estàs segur, realment segur que vols bloquejar totalment %@? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veureu contingut d’aquest domini i se suprimirà qualsevol dels vostres seguidors d’aquest domini."; +"Common.Alerts.BlockDomain.BlockEntireDomain" = "Bloca el domini"; +"Common.Alerts.BlockDomain.Title" = "Estàs totalment segur que vols bloquejar per complet %@? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veureu contingut d’aquest domini i se suprimirà qualsevol dels vostres seguidors d’aquest domini."; "Common.Alerts.CleanCache.Message" = "S'ha netejat correctament la memòria cau de %@."; "Common.Alerts.CleanCache.Title" = "Neteja la memòria cau"; -"Common.Alerts.Common.PleaseTryAgain" = "Si us plau intenta-ho de nou."; -"Common.Alerts.Common.PleaseTryAgainLater" = "Si us plau, prova-ho més tard."; -"Common.Alerts.DeletePost.Message" = "Estàs segur que vols suprimir aquesta publicació?"; -"Common.Alerts.DeletePost.Title" = "Esborrar Publicació"; -"Common.Alerts.DiscardPostContent.Message" = "Confirma per a descartar el contingut de la publicació composta."; +"Common.Alerts.Common.PleaseTryAgain" = "Torna-ho a provar."; +"Common.Alerts.Common.PleaseTryAgainLater" = "Prova-ho més tard."; +"Common.Alerts.DeletePost.Message" = "Segur que vols eliminar aquesta publicació?"; +"Common.Alerts.DeletePost.Title" = "Eliminar la publicació"; +"Common.Alerts.DiscardPostContent.Message" = "Confirma per a descartar el contingut de la publicació."; "Common.Alerts.DiscardPostContent.Title" = "Descarta l'esborrany"; -"Common.Alerts.EditProfileFailure.Message" = "No es pot editar el perfil. Si us plau torna-ho a provar."; -"Common.Alerts.EditProfileFailure.Title" = "Error al Editar el Perfil"; -"Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "No pots adjuntar més d'un vídeo."; +"Common.Alerts.EditProfileFailure.Message" = "No es pot editar el perfil. Torna-ho a provar."; +"Common.Alerts.EditProfileFailure.Title" = "Error en editar el perfil"; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "No es pot adjuntar més d'un vídeo."; "Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "No es pot adjuntar un vídeo a una publicació que ja contingui imatges."; "Common.Alerts.PublishPostFailure.Message" = "No s'ha pogut enviar la publicació. -Comprova la teva connexió a Internet."; -"Common.Alerts.PublishPostFailure.Title" = "Error de Publicació"; -"Common.Alerts.SavePhotoFailure.Message" = "Activa el permís d'accés a la biblioteca de fotos per desar-la."; -"Common.Alerts.SavePhotoFailure.Title" = "Error al Desar la Foto"; -"Common.Alerts.ServerError.Title" = "Error del Servidor"; -"Common.Alerts.SignOut.Confirm" = "Tancar Sessió"; -"Common.Alerts.SignOut.Message" = "Estàs segur que vols tancar la sessió?"; -"Common.Alerts.SignOut.Title" = "Tancar Sessió"; +Comprova la connexió a Internet."; +"Common.Alerts.PublishPostFailure.Title" = "Error en publicar"; +"Common.Alerts.SavePhotoFailure.Message" = "Activa el permís d'accés a la biblioteca de fotos per a desar-la."; +"Common.Alerts.SavePhotoFailure.Title" = "Error en desar la foto"; +"Common.Alerts.ServerError.Title" = "Error del servidor"; +"Common.Alerts.SignOut.Confirm" = "Tanca la sessió"; +"Common.Alerts.SignOut.Message" = "Segur que vols tancar la sessió?"; +"Common.Alerts.SignOut.Title" = "Tanca la sessió"; "Common.Alerts.SignUpFailure.Title" = "Error en el registre"; +"Common.Alerts.TranslationFailed.Button" = "D'acord"; +"Common.Alerts.TranslationFailed.Message" = "La traducció ha fallat. Potser l'administrador d'aquest servidor no ha activat les traduccions o està executant una versió vella de Mastodon on les traduccions encara no eren suportades."; +"Common.Alerts.TranslationFailed.Title" = "Nota"; "Common.Alerts.VoteFailure.PollEnded" = "L'enquesta ha finalitzat"; -"Common.Alerts.VoteFailure.Title" = "Error del Vot"; +"Common.Alerts.VoteFailure.Title" = "Error en votar"; "Common.Controls.Actions.Add" = "Afegeix"; "Common.Controls.Actions.Back" = "Enrere"; "Common.Controls.Actions.BlockDomain" = "Bloqueja %@"; "Common.Controls.Actions.Cancel" = "Cancel·la"; -"Common.Controls.Actions.Compose" = "Composa"; +"Common.Controls.Actions.Compose" = "Redacta"; "Common.Controls.Actions.Confirm" = "Confirma"; "Common.Controls.Actions.Continue" = "Continua"; +"Common.Controls.Actions.Copy" = "Copia"; "Common.Controls.Actions.CopyPhoto" = "Copia la foto"; "Common.Controls.Actions.Delete" = "Suprimeix"; "Common.Controls.Actions.Discard" = "Descarta"; @@ -50,21 +54,23 @@ Comprova la teva connexió a Internet."; "Common.Controls.Actions.ReportUser" = "Informa sobre %@"; "Common.Controls.Actions.Save" = "Desa"; "Common.Controls.Actions.SavePhoto" = "Desa la foto"; -"Common.Controls.Actions.SeeMore" = "Veure més"; +"Common.Controls.Actions.SeeMore" = "Mostra'n més"; "Common.Controls.Actions.Settings" = "Configuració"; "Common.Controls.Actions.Share" = "Comparteix"; -"Common.Controls.Actions.SharePost" = "Compartir Publicació"; -"Common.Controls.Actions.ShareUser" = "Compartir %@"; -"Common.Controls.Actions.SignIn" = "Iniciar sessió"; +"Common.Controls.Actions.SharePost" = "Comparteix la publicació"; +"Common.Controls.Actions.ShareUser" = "Comparteix %@"; +"Common.Controls.Actions.SignIn" = "Inicia sessió"; "Common.Controls.Actions.SignUp" = "Crea un compte"; "Common.Controls.Actions.Skip" = "Omet"; "Common.Controls.Actions.TakePhoto" = "Fes una foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Traduït del %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Desconegut"; "Common.Controls.Actions.TryAgain" = "Torna a provar"; "Common.Controls.Actions.UnblockDomain" = "Desbloqueja %@"; -"Common.Controls.Friendship.Block" = "Bloqueja"; -"Common.Controls.Friendship.BlockDomain" = "Bloqueja %@"; -"Common.Controls.Friendship.BlockUser" = "Bloqueja %@"; -"Common.Controls.Friendship.Blocked" = "Bloquejat"; +"Common.Controls.Friendship.Block" = "Bloca"; +"Common.Controls.Friendship.BlockDomain" = "Bloca %@"; +"Common.Controls.Friendship.BlockUser" = "Bloca %@"; +"Common.Controls.Friendship.Blocked" = "Blocat"; "Common.Controls.Friendship.EditInfo" = "Edita"; "Common.Controls.Friendship.Follow" = "Segueix"; "Common.Controls.Friendship.Following" = "Seguint"; @@ -73,10 +79,10 @@ Comprova la teva connexió a Internet."; "Common.Controls.Friendship.MuteUser" = "Silencia %@"; "Common.Controls.Friendship.Muted" = "Silenciat"; "Common.Controls.Friendship.Pending" = "Pendent"; -"Common.Controls.Friendship.Request" = "Petició"; +"Common.Controls.Friendship.Request" = "Sol·licitud"; "Common.Controls.Friendship.ShowReblogs" = "Mostra els impulsos"; -"Common.Controls.Friendship.Unblock" = "Desbloqueja"; -"Common.Controls.Friendship.UnblockUser" = "Desbloqueja %@"; +"Common.Controls.Friendship.Unblock" = "Desbloca"; +"Common.Controls.Friendship.UnblockUser" = "Desbloca %@"; "Common.Controls.Friendship.Unmute" = "Deixa de silenciar"; "Common.Controls.Friendship.UnmuteUser" = "Treure silenci de %@"; "Common.Controls.Keyboard.Common.ComposeNewPost" = "Redacta un nova publicació"; @@ -86,31 +92,34 @@ Comprova la teva connexió a Internet."; "Common.Controls.Keyboard.SegmentedControl.NextSection" = "Secció Següent"; "Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Secció Anterior"; "Common.Controls.Keyboard.Timeline.NextStatus" = "Publicació següent"; -"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Obre el Perfil de l'Autor"; -"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Obre el Perfil del Impulsor"; +"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Obre el perfil de l'autor"; +"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Obre el perfil de l'impuls"; "Common.Controls.Keyboard.Timeline.OpenStatus" = "Obre la publicació"; "Common.Controls.Keyboard.Timeline.PreviewImage" = "Vista prèvia de l'Imatge"; "Common.Controls.Keyboard.Timeline.PreviousStatus" = "Publicació anterior"; -"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Respon a la Publicació"; +"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Respon a la publicació"; "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Commuta l'Avís de Contingut"; "Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Commuta el Favorit de la Publicació"; "Common.Controls.Keyboard.Timeline.ToggleReblog" = "Commuta l'Impuls de la Publicació"; "Common.Controls.Status.Actions.Favorite" = "Favorit"; "Common.Controls.Status.Actions.Hide" = "Amaga"; "Common.Controls.Status.Actions.Menu" = "Menú"; -"Common.Controls.Status.Actions.Reblog" = "Impuls"; +"Common.Controls.Status.Actions.Reblog" = "Impulsa"; "Common.Controls.Status.Actions.Reply" = "Respon"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Compartir l'Enllaç en el Tut"; "Common.Controls.Status.Actions.ShowGif" = "Mostra el GIF"; "Common.Controls.Status.Actions.ShowImage" = "Mostra la imatge"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Mostra el reproductor de vídeo"; "Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Toca i manté per a veure el menú"; -"Common.Controls.Status.Actions.Unfavorite" = "Desfer Favorit"; -"Common.Controls.Status.Actions.Unreblog" = "Desfer l'impuls"; +"Common.Controls.Status.Actions.Unfavorite" = "Desfés el favorit"; +"Common.Controls.Status.Actions.Unreblog" = "Desfés l'impuls"; "Common.Controls.Status.ContentWarning" = "Advertència de Contingut"; +"Common.Controls.Status.LinkViaUser" = "%@ través de %@"; +"Common.Controls.Status.LoadEmbed" = "Carregar incrustat"; "Common.Controls.Status.MediaContentWarning" = "Toca qualsevol lloc per a mostrar"; "Common.Controls.Status.MetaEntity.Email" = "Correu electrònic: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Etiqueta %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Mostra el Perfil: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Etiqueta: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Mostra el perfil: %@"; "Common.Controls.Status.MetaEntity.Url" = "Enllaç: %@"; "Common.Controls.Status.Poll.Closed" = "Finalitzada"; "Common.Controls.Status.Poll.Vote" = "Vota"; @@ -118,38 +127,42 @@ Comprova la teva connexió a Internet."; "Common.Controls.Status.ShowPost" = "Mostra la Publicació"; "Common.Controls.Status.ShowUserProfile" = "Mostra el perfil de l'usuari"; "Common.Controls.Status.Tag.Email" = "Correu electrònic"; -"Common.Controls.Status.Tag.Emoji" = "Emoji"; +"Common.Controls.Status.Tag.Emoji" = "Emojis"; "Common.Controls.Status.Tag.Hashtag" = "Etiqueta"; "Common.Controls.Status.Tag.Link" = "Enllaç"; "Common.Controls.Status.Tag.Mention" = "Menciona"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Toca per a mostrar"; +"Common.Controls.Status.Translation.ShowOriginal" = "Mostra l'original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Desconegut"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ ha impulsat"; "Common.Controls.Status.UserRepliedTo" = "Ha respòs a %@"; "Common.Controls.Status.Visibility.Direct" = "Només l'usuari mencionat pot veure aquesta publicació."; "Common.Controls.Status.Visibility.Private" = "Només els seus seguidors poden veure aquesta publicació."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Només els meus seguidors poden veure aquesta publicació."; -"Common.Controls.Status.Visibility.Unlisted" = "Tothom pot veure aquesta publicació però no es mostra en la línia de temps pública."; +"Common.Controls.Status.Visibility.Unlisted" = "Tothom pot veure aquesta publicació, però no es mostra en la línia de temps pública."; "Common.Controls.Tabs.Home" = "Inici"; -"Common.Controls.Tabs.Notification" = "Notificació"; +"Common.Controls.Tabs.Notifications" = "Notificacions"; "Common.Controls.Tabs.Profile" = "Perfil"; -"Common.Controls.Tabs.Search" = "Cerca"; +"Common.Controls.Tabs.SearchAndExplore" = "Cerca i Explora"; "Common.Controls.Timeline.Filtered" = "Filtrat"; "Common.Controls.Timeline.Header.BlockedWarning" = "No pots veure el perfil d'aquest usuari -fins que et desbloquegi."; +fins que et desbloqui."; "Common.Controls.Timeline.Header.BlockingWarning" = "No pots veure el perfil d'aquest usuari - fins que el desbloquegis. +fins que el desbloquis. El teu perfil els sembla així."; "Common.Controls.Timeline.Header.NoStatusFound" = "No s'ha trobat cap publicació"; "Common.Controls.Timeline.Header.SuspendedWarning" = "Aquest usuari ha estat suspès."; "Common.Controls.Timeline.Header.UserBlockedWarning" = "No pots veure el perfil de %@ - fins que et desbloquegi."; + fins que et desbloqui."; "Common.Controls.Timeline.Header.UserBlockingWarning" = "No pots veure el perfil de %@ - fins que el desbloquegis. +fins que el desbloquis. El teu perfil els sembla així."; "Common.Controls.Timeline.Header.UserSuspendedWarning" = "El compte de %@ ha estat suspès."; -"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Carrega les publicacions faltants"; -"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Carregant les publicacions faltants..."; +"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Carrega les publicacions restants"; +"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Carregant les publicacions restants..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Mostra més respostes"; "Common.Controls.Timeline.Timestamp.Now" = "Ara"; "Scene.AccountList.AddAccount" = "Afegir compte"; @@ -161,8 +174,8 @@ El teu perfil els sembla així."; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Selector d'Emoji Personalitzat"; "Scene.Compose.Accessibility.DisableContentWarning" = "Desactiva l'Avís de Contingut"; "Scene.Compose.Accessibility.EnableContentWarning" = "Activa l'Avís de Contingut"; -"Scene.Compose.Accessibility.PostOptions" = "Opcions del tut"; -"Scene.Compose.Accessibility.PostVisibilityMenu" = "Menú de Visibilitat de Publicació"; +"Scene.Compose.Accessibility.PostOptions" = "Opcions del Tut"; +"Scene.Compose.Accessibility.PostVisibilityMenu" = "Menú de Visibilitat del Tut"; "Scene.Compose.Accessibility.PostingAs" = "Publicant com a %@"; "Scene.Compose.Accessibility.RemovePoll" = "Eliminar Enquesta"; "Scene.Compose.Attachment.AttachmentBroken" = "Aquest %@ està trencat i no pot ser @@ -170,8 +183,8 @@ carregat a Mastodon."; "Scene.Compose.Attachment.AttachmentTooLarge" = "El fitxer adjunt és massa gran"; "Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "No es pot reconèixer aquest adjunt multimèdia"; "Scene.Compose.Attachment.CompressingState" = "Comprimint..."; -"Scene.Compose.Attachment.DescriptionPhoto" = "Descriu la foto per als disminuïts visuals..."; -"Scene.Compose.Attachment.DescriptionVideo" = "Descriu el vídeo per als disminuïts visuals..."; +"Scene.Compose.Attachment.DescriptionPhoto" = "Descriu la foto per a les persones amb diversitat funcional..."; +"Scene.Compose.Attachment.DescriptionVideo" = "Descriu el vídeo per a les persones amb diversitat funcional..."; "Scene.Compose.Attachment.LoadFailed" = "Ha fallat la càrrega"; "Scene.Compose.Attachment.Photo" = "foto"; "Scene.Compose.Attachment.ServerProcessingState" = "Servidor processant..."; @@ -182,8 +195,8 @@ carregat a Mastodon."; "Scene.Compose.ContentInputPlaceholder" = "Escriu o enganxa el que tinguis en ment"; "Scene.Compose.ContentWarning.Placeholder" = "Escriu un advertiment precís aquí..."; "Scene.Compose.Keyboard.AppendAttachmentEntry" = "Afegeix Adjunt - %@"; -"Scene.Compose.Keyboard.DiscardPost" = "Descarta la Publicació"; -"Scene.Compose.Keyboard.PublishPost" = "Envia la Publicació"; +"Scene.Compose.Keyboard.DiscardPost" = "Descarta el Tut"; +"Scene.Compose.Keyboard.PublishPost" = "Envia el Tut"; "Scene.Compose.Keyboard.SelectVisibilityEntry" = "Selecciona la Visibilitat - %@"; "Scene.Compose.Keyboard.ToggleContentWarning" = "Commuta l'Avís de Contingut"; "Scene.Compose.Keyboard.TogglePoll" = "Commuta l'enquesta"; @@ -201,7 +214,7 @@ carregat a Mastodon."; "Scene.Compose.Poll.ThirtyMinutes" = "30 minuts"; "Scene.Compose.Poll.ThreeDays" = "3 Dies"; "Scene.Compose.ReplyingToUser" = "responent a %@"; -"Scene.Compose.Title.NewPost" = "Nova publicació"; +"Scene.Compose.Title.NewPost" = "Nou Tut"; "Scene.Compose.Title.NewReply" = "Nova Resposta"; "Scene.Compose.Visibility.Direct" = "Només les persones que menciono"; "Scene.Compose.Visibility.Private" = "Només seguidors"; @@ -219,16 +232,22 @@ carregat a Mastodon."; "Scene.ConfirmEmail.Subtitle" = "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte."; "Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte"; "Scene.ConfirmEmail.Title" = "Una última cosa."; -"Scene.Discovery.Intro" = "Aquestes son les publicacions que criden l'atenció en el teu racó de Mastodon."; +"Scene.Discovery.Intro" = "Aquests son els tuts que criden l'atenció en el teu racó de Mastodon."; "Scene.Discovery.Tabs.Community" = "Comunitat"; "Scene.Discovery.Tabs.ForYou" = "Per a tu"; "Scene.Discovery.Tabs.Hashtags" = "Etiquetes"; "Scene.Discovery.Tabs.News" = "Notícies"; -"Scene.Discovery.Tabs.Posts" = "Publicacions"; +"Scene.Discovery.Tabs.Posts" = "Tuts"; "Scene.Familiarfollowers.FollowedByNames" = "Seguit per %@"; "Scene.Familiarfollowers.Title" = "Seguidors coneguts"; "Scene.Favorite.Title" = "Els teus Favorits"; "Scene.FavoritedBy.Title" = "Preferit per"; +"Scene.FollowedTags.Actions.Follow" = "Segueix"; +"Scene.FollowedTags.Actions.Unfollow" = "Deixa de seguir"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "tuts"; +"Scene.FollowedTags.Header.PostsToday" = "tuts d'avui"; +"Scene.FollowedTags.Title" = "Etiquetes seguides"; "Scene.Follower.Footer" = "Els seguidors d'altres servidors no son mostrats."; "Scene.Follower.Title" = "seguidor"; "Scene.Following.Footer" = "Els seguits d'altres servidors no son mostrats."; @@ -266,29 +285,30 @@ carregat a Mastodon."; "Scene.Profile.Accessibility.ShowBannerImage" = "Mostra l'imatge del bàner"; "Scene.Profile.Dashboard.Followers" = "seguidors"; "Scene.Profile.Dashboard.Following" = "seguint"; -"Scene.Profile.Dashboard.Posts" = "publicacions"; +"Scene.Profile.Dashboard.Posts" = "tuts"; "Scene.Profile.Fields.AddRow" = "Afegeix fila"; +"Scene.Profile.Fields.Joined" = "S'hi va unir"; "Scene.Profile.Fields.Placeholder.Content" = "Contingut"; "Scene.Profile.Fields.Placeholder.Label" = "Etiqueta"; "Scene.Profile.Fields.Verified.Long" = "La propietat d'aquest enllaç es va verificar el dia %@"; "Scene.Profile.Fields.Verified.Short" = "Verificat a %@"; "Scene.Profile.Header.FollowsYou" = "Et segueix"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirma per a bloquejar %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloqueja el Compte"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirma per a blocar %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloca el Compte"; "Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirma per a amagar els impulsos"; "Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Amaga Impulsos"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirma per a silenciar %@"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Silencia el Compte"; "Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirma per a mostrar els impulsos"; "Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Mostra els Impulsos"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirma per a desbloquejar %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Desbloqueja el Compte"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirma per a desblocar %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Desbloca el Compte"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Confirma deixar de silenciar a %@"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Desfer silenciar compte"; "Scene.Profile.SegmentedControl.About" = "Quant a"; "Scene.Profile.SegmentedControl.Media" = "Mèdia"; -"Scene.Profile.SegmentedControl.Posts" = "Publicacions"; -"Scene.Profile.SegmentedControl.PostsAndReplies" = "Publicacions i Respostes"; +"Scene.Profile.SegmentedControl.Posts" = "Tuts"; +"Scene.Profile.SegmentedControl.PostsAndReplies" = "Tuts i Respostes"; "Scene.Profile.SegmentedControl.Replies" = "Respostes"; "Scene.RebloggedBy.Title" = "Impulsat per"; "Scene.Register.Error.Item.Agreement" = "Acord"; @@ -325,7 +345,7 @@ carregat a Mastodon."; "Scene.Register.Input.Username.Placeholder" = "nom d'usuari"; "Scene.Register.LetsGetYouSetUpOnDomain" = "Anem a configurar-te a %@"; "Scene.Register.Title" = "Anem a configurar-te a %@"; -"Scene.Report.Content1" = "Hi ha alguna altre publicació que vulguis afegir a l'informe?"; +"Scene.Report.Content1" = "Hi ha algun altre tut que vulguis afegir a l'informe?"; "Scene.Report.Content2" = "Hi ha alguna cosa que els moderadors hagin de saber sobre aquest informe?"; "Scene.Report.ReportSentTitle" = "Gràcies per informar, ho investigarem."; "Scene.Report.Reported" = "REPORTAT"; @@ -336,13 +356,13 @@ carregat a Mastodon."; "Scene.Report.StepFinal.BlockUser" = "Bloca %@"; "Scene.Report.StepFinal.DontWantToSeeThis" = "No vols veure això?"; "Scene.Report.StepFinal.MuteUser" = "Silencia %@"; -"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats."; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Ja no podran seguir ni veure els teus tus, però poden veure si han estat blocats."; "Scene.Report.StepFinal.Unfollow" = "Deixa de seguir"; "Scene.Report.StepFinal.UnfollowUser" = "Deixa de seguir %@"; "Scene.Report.StepFinal.Unfollowed" = "S'ha deixat de seguir"; -"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la vostra experiència."; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la teva experiència."; "Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Mentre ho revisem, pots prendre mesures contra %@"; -"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "No veuràs les seves publicacions o impulsos a la teva línia de temps personal. No sabran que han estat silenciats."; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "No veuràs els seus tuts o impulsos a la teva línia de temps personal. No sabran que han estat silenciats."; "Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Hi ha res més que hauríem de saber?"; "Scene.Report.StepFour.Step4Of4" = "Pas 4 de 4"; "Scene.Report.StepOne.IDontLikeIt" = "No m'agrada"; @@ -355,10 +375,10 @@ carregat a Mastodon."; "Scene.Report.StepOne.Step1Of4" = "Pas 1 de 4"; "Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "El problema no encaixa en altres categories"; "Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Quin és el problema amb aquest compte?"; -"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Quin és el problema amb aquesta publicació?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Quin és el problema amb aquest tut?"; "Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Quin és el problema amb %@?"; "Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Ets conscient que incompleix normes específiques"; -"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Hi ha alguna publicació que recolzi aquest informe?"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Hi ha alguns tuts que recolzin aquest informe?"; "Scene.Report.StepThree.SelectAllThatApply" = "Selecciona tot el que correspongui"; "Scene.Report.StepThree.Step3Of4" = "Pas 3 de 4"; "Scene.Report.StepTwo.IJustDon’tLikeIt" = "Simplement no m'agrada"; @@ -383,7 +403,7 @@ carregat a Mastodon."; "Scene.Search.Searching.Segment.All" = "Tots"; "Scene.Search.Searching.Segment.Hashtags" = "Etiquetes"; "Scene.Search.Searching.Segment.People" = "Gent"; -"Scene.Search.Searching.Segment.Posts" = "Publicacions"; +"Scene.Search.Searching.Segment.Posts" = "Tuts"; "Scene.Search.Title" = "Cerca"; "Scene.ServerPicker.Button.Category.Academia" = "acadèmia"; "Scene.ServerPicker.Button.Category.Activism" = "activisme"; @@ -409,7 +429,7 @@ carregat a Mastodon."; "Scene.ServerPicker.Label.Language" = "LLENGUATGE"; "Scene.ServerPicker.Label.Users" = "USUARIS"; "Scene.ServerPicker.Subtitle" = "Tria un servidor en funció de la teva regió, interessos o un de propòsit general. Seguiràs podent connectar amb tothom a Mastodon, independentment del servidor."; -"Scene.ServerPicker.Title" = "Mastodon està fet d'usuaris en diferents comunitats."; +"Scene.ServerPicker.Title" = "Mastodon està fet d'usuaris en diferents servidors."; "Scene.ServerRules.Button.Confirm" = "Hi estic d'acord"; "Scene.ServerRules.PrivacyPolicy" = "política de privadesa"; "Scene.ServerRules.Prompt" = "Al continuar, estàs subjecte als termes de servei i a la política de privacitat de %@."; @@ -431,8 +451,8 @@ carregat a Mastodon."; "Scene.Settings.Section.LookAndFeel.SortaDark" = "Una Mena de Fosc"; "Scene.Settings.Section.LookAndFeel.Title" = "Aspecte i Comportament"; "Scene.Settings.Section.LookAndFeel.UseSystem" = "Usa el del Sistema"; -"Scene.Settings.Section.Notifications.Boosts" = "Ha impulsat el meu estat"; -"Scene.Settings.Section.Notifications.Favorites" = "Ha afavorit el meu estat"; +"Scene.Settings.Section.Notifications.Boosts" = "Ha impulsat el meu tut"; +"Scene.Settings.Section.Notifications.Favorites" = "Ha afavorit el meu tut"; "Scene.Settings.Section.Notifications.Follows" = "Em segueix"; "Scene.Settings.Section.Notifications.Mentions" = "M'ha mencionat"; "Scene.Settings.Section.Notifications.Title" = "Notificacions"; @@ -451,10 +471,10 @@ carregat a Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Tancar Sessió"; "Scene.Settings.Section.SpicyZone.Title" = "La Zona Picant"; "Scene.Settings.Title" = "Configuració"; -"Scene.SuggestionAccount.FollowExplain" = "Quan segueixes algú, veuràs les seves publicacions a Inici."; +"Scene.SuggestionAccount.FollowExplain" = "Quan segueixes algú, veuràs els seus tuts a Inici."; "Scene.SuggestionAccount.Title" = "Cerca Persones a Seguir"; -"Scene.Thread.BackTitle" = "Publicació"; -"Scene.Thread.Title" = "Publicació de %@"; +"Scene.Thread.BackTitle" = "Tut"; +"Scene.Thread.Title" = "Tut de %@"; "Scene.Welcome.GetStarted" = "Comença"; "Scene.Welcome.LogIn" = "Inicia sessió"; "Scene.Welcome.Slogan" = "Xarxa social diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict index 947597417..615fd0c48 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict @@ -408,7 +408,7 @@ NSStringFormatValueTypeKey ld one - fa 1 día + fa 1 dia other fa %ld dies @@ -424,7 +424,7 @@ NSStringFormatValueTypeKey ld one - fa 1h + fa 1 h other fa %ld hores @@ -440,9 +440,9 @@ NSStringFormatValueTypeKey ld one - fa 1 minut + fa 1 min other - fa %ld minuts + fa %ld min date.second.ago.abbr @@ -456,9 +456,9 @@ NSStringFormatValueTypeKey ld one - fa 1 segon + fa 1 s other - fa %ld segons + fa %ld s diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 4e76e20fb..5f6f124a1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "دڵنیایت دەتەوێت دەربچیت؟"; "Common.Alerts.SignOut.Title" = "دەربچۆ"; "Common.Alerts.SignUpFailure.Title" = "تۆمارکردنەکە سەرکەوتوو نەبوو"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "دەنگدانەکە کۆتایی هاتووە"; "Common.Alerts.VoteFailure.Title" = "نەتوانرا دەنگ بدرێت"; "Common.Controls.Actions.Add" = "زیادی بکە"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "پۆست بکە"; "Common.Controls.Actions.Confirm" = "پشتڕاستی بکەوە"; "Common.Controls.Actions.Continue" = "بەردەوام بە"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "لەبەری بگرەوە"; "Common.Controls.Actions.Delete" = "بیسڕەوە"; "Common.Controls.Actions.Discard" = "وازی لێ بێنە"; @@ -59,6 +63,8 @@ "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "بیپەڕێنە"; "Common.Controls.Actions.TakePhoto" = "وێنە بگرە"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "هەوڵ بدەوە"; "Common.Controls.Actions.UnblockDomain" = "%@ ئاستەنگ مەکە"; "Common.Controls.Friendship.Block" = "ئاستەنگی بکە"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "پێڕست"; "Common.Controls.Status.Actions.Reblog" = "پۆستی بکەوە"; "Common.Controls.Status.Actions.Reply" = "وەڵامی بدەوە"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "گیفەکە نیشان بدە"; "Common.Controls.Status.Actions.ShowImage" = "وێنەکە نیشان بدە"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "ڤیدیۆکە لێ بدە"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "بەدڵبوونەکە بگەڕێنەوە"; "Common.Controls.Status.Actions.Unreblog" = "پۆستکردنەکە بگەڕێنەوە"; "Common.Controls.Status.ContentWarning" = "ئاگاداریی ناوەڕۆک"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "دەستی پیا بنێ بۆ نیشاندانی"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "ئاماژە"; "Common.Controls.Status.Tag.Url" = "بەستەر"; "Common.Controls.Status.TapToReveal" = "دەستی پیا بنێ بۆ نیشاندانی"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ پۆست کرایەوە"; "Common.Controls.Status.UserRepliedTo" = "لە وەڵامدا بۆ %@"; "Common.Controls.Status.Visibility.Direct" = "تەنیا بەکارهێنەرە ئاماژە پێکراوەکە دەتوانێت ئەم پۆستە ببینێت."; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "تەنیا شوێنکەوتووەکانم دەتوانن ئەم پۆستە ببینن."; "Common.Controls.Status.Visibility.Unlisted" = "هەرکەسێک دەتوانێت ئەم پۆستە ببینێت بەڵام ناچێتە بەردەمیان."; "Common.Controls.Tabs.Home" = "ماڵەوە"; -"Common.Controls.Tabs.Notification" = "ئاگادارکردنەوەکان"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "پرۆفایل"; -"Common.Controls.Tabs.Search" = "بگەڕێ"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "پاڵێوراو"; "Common.Controls.Timeline.Header.BlockedWarning" = "ناتوانیت پرۆفایلی ئەم بەکارهێنەرە ببینیت تا ئەو کاتەی ئاستەنگەکەت لادەبات."; @@ -228,6 +241,12 @@ "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "بەدڵبووەکانت"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "شوێنکەوتووەکانی لە ڕاژەکارەکانی ترەوە نیشان نادرێت."; "Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; @@ -267,6 +286,7 @@ "Scene.Profile.Dashboard.Following" = "شوێنکەوتن"; "Scene.Profile.Dashboard.Posts" = "پۆستەکان"; "Scene.Profile.Fields.AddRow" = "ڕیز زیاد بکە"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "ناوەڕۆک"; "Scene.Profile.Fields.Placeholder.Label" = "ناونیشان"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings index 22260e380..8a8a977b7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings @@ -22,6 +22,9 @@ Zkontrolujte prosím připojení k internetu."; "Common.Alerts.SignOut.Message" = "Opravdu se chcete odhlásit?"; "Common.Alerts.SignOut.Title" = "Odhlásit se"; "Common.Alerts.SignUpFailure.Title" = "Registrace selhala"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Anketa skončila"; "Common.Alerts.VoteFailure.Title" = "Selhání hlasování"; "Common.Controls.Actions.Add" = "Přidat"; @@ -31,6 +34,7 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.Compose" = "Napsat"; "Common.Controls.Actions.Confirm" = "Potvrdit"; "Common.Controls.Actions.Continue" = "Pokračovat"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Kopírovat fotografii"; "Common.Controls.Actions.Delete" = "Smazat"; "Common.Controls.Actions.Discard" = "Zahodit"; @@ -59,6 +63,8 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.SignUp" = "Vytvořit účet"; "Common.Controls.Actions.Skip" = "Přeskočit"; "Common.Controls.Actions.TakePhoto" = "Vyfotit"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Zkusit znovu"; "Common.Controls.Actions.UnblockDomain" = "Odblokovat %@"; "Common.Controls.Friendship.Block" = "Blokovat"; @@ -94,12 +100,13 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Keyboard.Timeline.ReplyStatus" = "Odpovědět na příspěvek"; "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Přepnout varování obsahu"; "Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Toggle Favorite on Post"; -"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Toggle Reblog on Post"; +"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Přepnout Reblog na příspěvku"; "Common.Controls.Status.Actions.Favorite" = "Oblíbit"; "Common.Controls.Status.Actions.Hide" = "Skrýt"; "Common.Controls.Status.Actions.Menu" = "Nabídka"; "Common.Controls.Status.Actions.Reblog" = "Boostnout"; "Common.Controls.Status.Actions.Reply" = "Odpovědět"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Zobrazit GIF"; "Common.Controls.Status.Actions.ShowImage" = "Zobrazit obrázek"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Zobrazit video přehrávač"; @@ -107,6 +114,8 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Status.Actions.Unfavorite" = "Odebrat z oblízených"; "Common.Controls.Status.Actions.Unreblog" = "Undo reblog"; "Common.Controls.Status.ContentWarning" = "Varování o obsahu"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Klepnutím kdekoli zobrazíte"; "Common.Controls.Status.MetaEntity.Email" = "E-mailová adresa: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Status.Tag.Mention" = "Zmínka"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Klepnutím zobrazit"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ reblogged"; "Common.Controls.Status.UserRepliedTo" = "Odpověděl %@"; "Common.Controls.Status.Visibility.Direct" = "Pouze zmíněný uživatel může vidět tento příspěvek."; @@ -131,9 +144,9 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Pouze moji sledující mohou vidět tento příspěvek."; "Common.Controls.Status.Visibility.Unlisted" = "Každý může vidět tento příspěvek, ale nezobrazovat ve veřejné časové ose."; "Common.Controls.Tabs.Home" = "Domů"; -"Common.Controls.Tabs.Notification" = "Oznamování"; +"Common.Controls.Tabs.Notifications" = "Oznámení"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Hledat"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Filtrováno"; "Common.Controls.Timeline.Header.BlockedWarning" = "Nemůžeš zobrazit profil tohoto uživatele, dokud tě neodblokují."; "Common.Controls.Timeline.Header.BlockingWarning" = "Nemůžete zobrazit profil tohoto uživatele, dokud ho neodblokujete. @@ -225,6 +238,12 @@ nahrán do Mastodonu."; "Scene.Familiarfollowers.Title" = "Sledující, které znáte"; "Scene.Favorite.Title" = "Vaše oblíbené"; "Scene.FavoritedBy.Title" = "Oblíben"; +"Scene.FollowedTags.Actions.Follow" = "Sledovat"; +"Scene.FollowedTags.Actions.Unfollow" = "Přestat sledovat"; +"Scene.FollowedTags.Header.Participants" = "účastníci"; +"Scene.FollowedTags.Header.Posts" = "příspěvky"; +"Scene.FollowedTags.Header.PostsToday" = "příspěvky dnes"; +"Scene.FollowedTags.Title" = "Sledované štítky"; "Scene.Follower.Footer" = "Sledující z jiných serverů nejsou zobrazeni."; "Scene.Follower.Title" = "sledující"; "Scene.Following.Footer" = "Sledování z jiných serverů není zobrazeno."; @@ -264,6 +283,7 @@ nahrán do Mastodonu."; "Scene.Profile.Dashboard.Following" = "sledování"; "Scene.Profile.Dashboard.Posts" = "příspěvky"; "Scene.Profile.Fields.AddRow" = "Přidat řádek"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Obsah"; "Scene.Profile.Fields.Placeholder.Label" = "Označení"; "Scene.Profile.Fields.Verified.Long" = "Vlastnictví tohoto odkazu bylo zkontrolováno na %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 29f3d16f5..74dbaeea6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -5,7 +5,7 @@ "Common.Alerts.Common.PleaseTryAgain" = "Bitte versuche es erneut."; "Common.Alerts.Common.PleaseTryAgainLater" = "Bitte versuche es später nochmal."; "Common.Alerts.DeletePost.Message" = "Bist du dir sicher, dass du diesen Beitrag löschen willst?"; -"Common.Alerts.DeletePost.Title" = "Bist du dir sicher, dass du diesen Beitrag löschen möchtest?"; +"Common.Alerts.DeletePost.Title" = "Beiträge löschen"; "Common.Alerts.DiscardPostContent.Message" = "Bestätige, um den Beitrag zu verwerfen."; "Common.Alerts.DiscardPostContent.Title" = "Entwurf verwerfen"; "Common.Alerts.EditProfileFailure.Message" = "Profil kann nicht bearbeitet werden. Bitte versuche es erneut."; @@ -22,6 +22,9 @@ Bitte überprüfe deine Internetverbindung."; "Common.Alerts.SignOut.Message" = "Bist du sicher, dass du dich abmelden möchten?"; "Common.Alerts.SignOut.Title" = "Abmelden"; "Common.Alerts.SignUpFailure.Title" = "Registrierungsfehler"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Übersetzung fehlgeschlagen. Möglicherweise hat der/die Administrator*in die Übersetzungen auf diesem Server nicht aktiviert oder dieser Server läuft mit einer älteren Version von Mastodon, in der Übersetzungen noch nicht unterstützt wurden."; +"Common.Alerts.TranslationFailed.Title" = "Hinweis"; "Common.Alerts.VoteFailure.PollEnded" = "Die Umfrage ist beendet"; "Common.Alerts.VoteFailure.Title" = "Fehler bei Abstimmung"; "Common.Controls.Actions.Add" = "Hinzufügen"; @@ -30,13 +33,14 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.Cancel" = "Abbrechen"; "Common.Controls.Actions.Compose" = "Neue Nachricht"; "Common.Controls.Actions.Confirm" = "Bestätigen"; -"Common.Controls.Actions.Continue" = "Fortfahren"; +"Common.Controls.Actions.Continue" = "Weiter"; +"Common.Controls.Actions.Copy" = "Kopieren"; "Common.Controls.Actions.CopyPhoto" = "Foto kopieren"; "Common.Controls.Actions.Delete" = "Löschen"; "Common.Controls.Actions.Discard" = "Verwerfen"; "Common.Controls.Actions.Done" = "Fertig"; "Common.Controls.Actions.Edit" = "Bearbeiten"; -"Common.Controls.Actions.FindPeople" = "Finde Personen zum Folgen"; +"Common.Controls.Actions.FindPeople" = "Personen zum Folgen finden"; "Common.Controls.Actions.ManuallySearch" = "Stattdessen manuell suchen"; "Common.Controls.Actions.Next" = "Weiter"; "Common.Controls.Actions.Ok" = "OK"; @@ -59,6 +63,8 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.SignUp" = "Konto erstellen"; "Common.Controls.Actions.Skip" = "Überspringen"; "Common.Controls.Actions.TakePhoto" = "Foto aufnehmen"; +"Common.Controls.Actions.TranslatePost.Title" = "Von %@ übersetzen"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unbekannt"; "Common.Controls.Actions.TryAgain" = "Nochmals versuchen"; "Common.Controls.Actions.UnblockDomain" = "Blockierung von %@ aufheben"; "Common.Controls.Friendship.Block" = "Blockieren"; @@ -67,14 +73,14 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Friendship.Blocked" = "Blockiert"; "Common.Controls.Friendship.EditInfo" = "Information bearbeiten"; "Common.Controls.Friendship.Follow" = "Folgen"; -"Common.Controls.Friendship.Following" = "Folge Ich"; -"Common.Controls.Friendship.HideReblogs" = "Reblogs ausblenden"; +"Common.Controls.Friendship.Following" = "Gefolgt"; +"Common.Controls.Friendship.HideReblogs" = "Teilen ausblenden"; "Common.Controls.Friendship.Mute" = "Stummschalten"; "Common.Controls.Friendship.MuteUser" = "%@ stummschalten"; "Common.Controls.Friendship.Muted" = "Stummgeschaltet"; "Common.Controls.Friendship.Pending" = "In Warteschlange"; "Common.Controls.Friendship.Request" = "Anfragen"; -"Common.Controls.Friendship.ShowReblogs" = "Reblogs anzeigen"; +"Common.Controls.Friendship.ShowReblogs" = "Teilen anzeigen"; "Common.Controls.Friendship.Unblock" = "Blockierung aufheben"; "Common.Controls.Friendship.UnblockUser" = "Blockierung von %@ aufheben"; "Common.Controls.Friendship.Unmute" = "Nicht mehr stummschalten"; @@ -100,6 +106,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Status.Actions.Menu" = "Menü"; "Common.Controls.Status.Actions.Reblog" = "Teilen"; "Common.Controls.Status.Actions.Reply" = "Antworten"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Link im Beitrag teilen"; "Common.Controls.Status.Actions.ShowGif" = "GIF anzeigen"; "Common.Controls.Status.Actions.ShowImage" = "Bild anzeigen"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Zeige Video-Player"; @@ -107,10 +114,12 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Status.Actions.Unfavorite" = "Aus Favoriten entfernen"; "Common.Controls.Status.Actions.Unreblog" = "Nicht mehr teilen"; "Common.Controls.Status.ContentWarning" = "Inhaltswarnung"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Eingebettetes laden"; "Common.Controls.Status.MediaContentWarning" = "Tippe irgendwo zum Anzeigen"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; +"Common.Controls.Status.MetaEntity.Email" = "E-Mail-Adresse: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Profil anzeigen: %@"; "Common.Controls.Status.MetaEntity.Url" = "Link: %@"; "Common.Controls.Status.Poll.Closed" = "Beendet"; "Common.Controls.Status.Poll.Vote" = "Abstimmen"; @@ -124,16 +133,20 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Status.Tag.Mention" = "Erwähnung"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Zum Anzeigen tippen"; +"Common.Controls.Status.Translation.ShowOriginal" = "Original anzeigen"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unbekannt"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ teilte"; "Common.Controls.Status.UserRepliedTo" = "Antwortet auf %@"; "Common.Controls.Status.Visibility.Direct" = "Nur erwähnte Benutzer können diesen Beitrag sehen."; -"Common.Controls.Status.Visibility.Private" = "Nur Follower des Authors können diesen Beitrag sehen."; -"Common.Controls.Status.Visibility.PrivateFromMe" = "Nur meine Follower können diesen Beitrag sehen."; +"Common.Controls.Status.Visibility.Private" = "Nur die, die dem Autor folgen, können diesen Beitrag sehen."; +"Common.Controls.Status.Visibility.PrivateFromMe" = "Nur die, die mir folgen, können diesen Beitrag sehen."; "Common.Controls.Status.Visibility.Unlisted" = "Jeder kann diesen Post sehen, aber nicht in der öffentlichen Timeline zeigen."; "Common.Controls.Tabs.Home" = "Startseite"; -"Common.Controls.Tabs.Notification" = "Benachrichtigungen"; +"Common.Controls.Tabs.Notifications" = "Mitteilungen"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Suche"; +"Common.Controls.Tabs.SearchAndExplore" = "Suchen und Entdecken"; "Common.Controls.Timeline.Filtered" = "Gefiltert"; "Common.Controls.Timeline.Header.BlockedWarning" = "Das Profil dieses Benutzers kann nicht angezeigt werden, bis er dich entsperrt."; @@ -149,7 +162,7 @@ solange du diesen Benutzer nicht entsperrst. Dein Profil sieht für diesen Benutzer auch so aus."; "Common.Controls.Timeline.Header.UserSuspendedWarning" = "Das Konto von %@ wurde gesperrt."; "Common.Controls.Timeline.Loader.LoadMissingPosts" = "Fehlende Beiträge laden"; -"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Lade fehlende Beiträge..."; +"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Fehlende Beiträge werden geladen …"; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Weitere Antworten anzeigen"; "Common.Controls.Timeline.Timestamp.Now" = "Gerade"; "Scene.AccountList.AddAccount" = "Konto hinzufügen"; @@ -161,26 +174,26 @@ Dein Profil sieht für diesen Benutzer auch so aus."; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Benutzerdefinierter Emojiwähler"; "Scene.Compose.Accessibility.DisableContentWarning" = "Inhaltswarnung ausschalten"; "Scene.Compose.Accessibility.EnableContentWarning" = "Inhaltswarnung einschalten"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "Beitragsoptionen"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Sichtbarkeitsmenü"; -"Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; +"Scene.Compose.Accessibility.PostingAs" = "Veröffentlichen als %@"; "Scene.Compose.Accessibility.RemovePoll" = "Umfrage entfernen"; "Scene.Compose.Attachment.AttachmentBroken" = "Dieses %@ scheint defekt zu sein und kann nicht auf Mastodon hochgeladen werden."; "Scene.Compose.Attachment.AttachmentTooLarge" = "Anhang zu groß"; "Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Medienanhang wurde nicht erkannt"; -"Scene.Compose.Attachment.CompressingState" = "Komprimieren..."; -"Scene.Compose.Attachment.DescriptionPhoto" = "Für Menschen mit Sehbehinderung beschreiben..."; -"Scene.Compose.Attachment.DescriptionVideo" = "Für Menschen mit Sehbehinderung beschreiben..."; +"Scene.Compose.Attachment.CompressingState" = "wird komprimiert …"; +"Scene.Compose.Attachment.DescriptionPhoto" = "Für Menschen mit Sehbehinderung beschreiben …"; +"Scene.Compose.Attachment.DescriptionVideo" = "Für Menschen mit Sehbehinderung beschreiben …"; "Scene.Compose.Attachment.LoadFailed" = "Laden fehlgeschlagen"; "Scene.Compose.Attachment.Photo" = "Foto"; -"Scene.Compose.Attachment.ServerProcessingState" = "Serververarbeitung..."; +"Scene.Compose.Attachment.ServerProcessingState" = "Serververarbeitung …"; "Scene.Compose.Attachment.UploadFailed" = "Upload fehlgeschlagen"; "Scene.Compose.Attachment.Video" = "Video"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Leerzeichen um hinzuzufügen"; "Scene.Compose.ComposeAction" = "Veröffentlichen"; "Scene.Compose.ContentInputPlaceholder" = "Tippe oder füge ein, was dir am Herzen liegt"; -"Scene.Compose.ContentWarning.Placeholder" = "Schreibe eine Inhaltswarnung hier..."; +"Scene.Compose.ContentWarning.Placeholder" = "Hier eine Inhaltswarnung schreiben …"; "Scene.Compose.Keyboard.AppendAttachmentEntry" = "Anhang hinzufügen - %@"; "Scene.Compose.Keyboard.DiscardPost" = "Beitrag verwerfen"; "Scene.Compose.Keyboard.PublishPost" = "Beitrag veröffentlichen"; @@ -213,7 +226,7 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "E-Mail erneut versenden"; "Scene.ConfirmEmail.DontReceiveEmail.Title" = "Bitte überprüfe deine E-Mails"; "Scene.ConfirmEmail.OpenEmailApp.Description" = "Wir haben dir gerade eine E-Mail geschickt. Überprüfe deinen Spam-Ordner, falls du es noch nicht getan hast."; -"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "E-Mail"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "E-Mail-Client öffnen"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Überprüfe deinen Posteingang."; "Scene.ConfirmEmail.Subtitle" = "Schaue kurz in dein E-Mail-Postfach und tippe den Link an, den wir dir gesendet haben."; @@ -226,19 +239,25 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Discovery.Tabs.News" = "Nachrichten"; "Scene.Discovery.Tabs.Posts" = "Beiträge"; "Scene.Familiarfollowers.FollowedByNames" = "Gefolgt von %@"; -"Scene.Familiarfollowers.Title" = "Follower, die dir bekannt vorkommen"; +"Scene.Familiarfollowers.Title" = "Folgende, die du kennst"; "Scene.Favorite.Title" = "Deine Favoriten"; "Scene.FavoritedBy.Title" = "Favorisiert von"; -"Scene.Follower.Footer" = "Folger, die nicht auf deinem Server registriert sind, werden nicht angezeigt."; -"Scene.Follower.Title" = "Follower"; +"Scene.FollowedTags.Actions.Follow" = "Folgen"; +"Scene.FollowedTags.Actions.Unfollow" = "Entfolgen"; +"Scene.FollowedTags.Header.Participants" = "Teilnehmer*innen"; +"Scene.FollowedTags.Header.Posts" = "Beiträge"; +"Scene.FollowedTags.Header.PostsToday" = "Beiträge heute"; +"Scene.FollowedTags.Title" = "Gefolgte Hashtags"; +"Scene.Follower.Footer" = "Folgende, die nicht auf deinem Server registriert sind, werden nicht angezeigt."; +"Scene.Follower.Title" = "Folgende"; "Scene.Following.Footer" = "Gefolgte, die nicht auf deinem Server registriert sind, werden nicht angezeigt."; -"Scene.Following.Title" = "Folgende"; +"Scene.Following.Title" = "Gefolgte"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Zum Scrollen nach oben tippen und zum vorherigen Ort erneut tippen"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo-Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Neue Beiträge anzeigen"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Veröffentlicht!"; -"Scene.HomeTimeline.NavigationBarState.Publishing" = "Beitrag wird veröffentlicht..."; +"Scene.HomeTimeline.NavigationBarState.Publishing" = "Beitrag wird veröffentlicht …"; "Scene.HomeTimeline.Title" = "Startseite"; "Scene.Login.ServerSearchField.Placeholder" = "URL eingeben oder nach Server suchen"; "Scene.Login.Subtitle" = "Melden Sie sich auf dem Server an, auf dem Sie Ihr Konto erstellt haben."; @@ -268,6 +287,7 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Profile.Dashboard.Following" = "Gefolgte"; "Scene.Profile.Dashboard.Posts" = "Beiträge"; "Scene.Profile.Fields.AddRow" = "Zeile hinzufügen"; +"Scene.Profile.Fields.Joined" = "Beigetreten"; "Scene.Profile.Fields.Placeholder.Content" = "Inhalt"; "Scene.Profile.Fields.Placeholder.Label" = "Bezeichnung"; "Scene.Profile.Fields.Verified.Long" = "Besitz des Links wurde überprüft am %@"; @@ -275,12 +295,12 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Profile.Header.FollowsYou" = "Folgt dir"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bestätige %@ zu blockieren"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Konto blockieren"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Reblogs ausblenden"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Bestätigen, um Teilen auszublenden"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Teilen ausblenden"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bestätige %@ stumm zu schalten"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Konto stummschalten"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Bestätigen um Reblogs anzuzeigen"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Reblogs anzeigen"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Bestätigen, um Teilen anzuzeigen"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Teilen anzeigen"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Bestätige %@ zu entsperren"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Konto entsperren"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Bestätige um %@ nicht mehr stummzuschalten"; @@ -368,7 +388,7 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Report.TextPlaceholder" = "Zusätzliche Kommentare eingeben oder einfügen"; "Scene.Report.Title" = "%@ melden"; "Scene.Report.TitleReport" = "Melden"; -"Scene.Search.Recommend.Accounts.Description" = "Vielleicht gefallen dir diese Benutzer"; +"Scene.Search.Recommend.Accounts.Description" = "Vielleicht gefallen dir diese Konten"; "Scene.Search.Recommend.Accounts.Follow" = "Folgen"; "Scene.Search.Recommend.Accounts.Title" = "Konten, die dir gefallen könnten"; "Scene.Search.Recommend.ButtonText" = "Alle anzeigen"; @@ -402,7 +422,7 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.ServerPicker.Button.SeeLess" = "Weniger anzeigen"; "Scene.ServerPicker.Button.SeeMore" = "Mehr anzeigen"; "Scene.ServerPicker.EmptyState.BadNetwork" = "Beim Laden der Daten ist etwas schief gelaufen. Überprüfe deine Internetverbindung."; -"Scene.ServerPicker.EmptyState.FindingServers" = "Verfügbare Server werden gesucht..."; +"Scene.ServerPicker.EmptyState.FindingServers" = "Verfügbare Server werden gesucht …"; "Scene.ServerPicker.EmptyState.NoResults" = "Keine Ergebnisse"; "Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Suche nach einer Community oder gib eine URL ein"; "Scene.ServerPicker.Label.Category" = "KATEGORIE"; @@ -452,7 +472,7 @@ beliebigen Server."; "Scene.Settings.Section.SpicyZone.Signout" = "Abmelden"; "Scene.Settings.Section.SpicyZone.Title" = "Der Gefährliche Bereich"; "Scene.Settings.Title" = "Einstellungen"; -"Scene.SuggestionAccount.FollowExplain" = "Wenn du jemandem folgst, dann siehst du deren Beiträge in deinem Home-Feed."; +"Scene.SuggestionAccount.FollowExplain" = "Sobald du anderen folgst, siehst du deren Beiträge in deinem Home-Feed."; "Scene.SuggestionAccount.Title" = "Finde Personen zum Folgen"; "Scene.Thread.BackTitle" = "Beitrag"; "Scene.Thread.Title" = "Beitrag von %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict index 1965fd02b..9d07f80d1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict @@ -37,7 +37,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Noch %#@character_count@ übrig + Noch %#@character_count@ Zeichen übrig character_count NSStringFormatSpecTypeKey @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ übrig character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 Zeichen other - %ld characters + %ld Zeichen plural.count.followed_by_and_mutual diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index ea106ffd2..cbef8ddbb 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -22,9 +22,9 @@ Please check your internet connection."; "Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?"; "Common.Alerts.SignOut.Title" = "Sign Out"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; -"Common.Alerts.TranslationFailed.Title" = "Note"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "The poll has ended"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Add"; @@ -34,6 +34,7 @@ Please check your internet connection."; "Common.Controls.Actions.Compose" = "Compose"; "Common.Controls.Actions.Confirm" = "Confirm"; "Common.Controls.Actions.Continue" = "Continue"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Copy Photo"; "Common.Controls.Actions.Delete" = "Delete"; "Common.Controls.Actions.Discard" = "Discard"; @@ -62,9 +63,8 @@ Please check your internet connection."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; -"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@ using %@"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; -"Common.Controls.Actions.TranslatePost.UnknownProvider" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; "Common.Controls.Friendship.Block" = "Block"; @@ -106,6 +106,7 @@ Please check your internet connection."; "Common.Controls.Status.Actions.Menu" = "Menu"; "Common.Controls.Status.Actions.Reblog" = "Reblog"; "Common.Controls.Status.Actions.Reply" = "Reply"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Show GIF"; "Common.Controls.Status.Actions.ShowImage" = "Show image"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; @@ -113,6 +114,8 @@ Please check your internet connection."; "Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; "Common.Controls.Status.Actions.Unreblog" = "Undo reblog"; "Common.Controls.Status.ContentWarning" = "Content Warning"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -130,7 +133,7 @@ Please check your internet connection."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; "Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; "Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; @@ -141,9 +144,9 @@ Please check your internet connection."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; "Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Home"; -"Common.Controls.Tabs.Notification" = "Notification"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profile"; -"Common.Controls.Tabs.Search" = "Search"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Filtered"; "Common.Controls.Timeline.Header.BlockedWarning" = "You can’t view this user’s profile until they unblock you."; @@ -239,12 +242,18 @@ uploaded to Mastodon."; "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Your Favorites"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; "Scene.Following.Title" = "following"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; @@ -278,6 +287,7 @@ uploaded to Mastodon."; "Scene.Profile.Dashboard.Following" = "following"; "Scene.Profile.Dashboard.Posts" = "posts"; "Scene.Profile.Fields.AddRow" = "Add Row"; +"Scene.Profile.Fields.Joined" = "Liitytty"; "Scene.Profile.Fields.Placeholder.Content" = "Content"; "Scene.Profile.Fields.Placeholder.Label" = "Label"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; @@ -471,4 +481,4 @@ uploaded to Mastodon."; back in your hands."; "Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; "Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; +"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict index 297e6675a..788eb95fc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds @@ -60,14 +60,8 @@ NSStringPluralRuleType NSStringFormatValueTypeKey ld - zero - no characters one 1 character - few - %ld characters - many - %ld characters other %ld characters diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index b2cb18954..d9d6a6ff6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -22,6 +22,9 @@ Por favor, revise su conexión a internet."; "Common.Alerts.SignOut.Message" = "¿Estás seguro de que deseas cerrar la sesión?"; "Common.Alerts.SignOut.Title" = "Cerrar Sesión"; "Common.Alerts.SignUpFailure.Title" = "Error al registrarse"; +"Common.Alerts.TranslationFailed.Button" = "Aceptar"; +"Common.Alerts.TranslationFailed.Message" = "Error al traducir. Tal vez el administrador no ha habilitado las traducciones en este servidor o este servidor está ejecutando una versión antigua de Mastodon donde las traducciones aún no están soportadas."; +"Common.Alerts.TranslationFailed.Title" = "Nota"; "Common.Alerts.VoteFailure.PollEnded" = "La encuesta ha terminado"; "Common.Alerts.VoteFailure.Title" = "Voto fallido"; "Common.Controls.Actions.Add" = "Añadir"; @@ -31,6 +34,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.Compose" = "Redactar"; "Common.Controls.Actions.Confirm" = "Confirmar"; "Common.Controls.Actions.Continue" = "Continuar"; +"Common.Controls.Actions.Copy" = "Copiar"; "Common.Controls.Actions.CopyPhoto" = "Copiar foto"; "Common.Controls.Actions.Delete" = "Borrar"; "Common.Controls.Actions.Discard" = "Descartar"; @@ -55,10 +59,12 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.Share" = "Compartir"; "Common.Controls.Actions.SharePost" = "Compartir publicación"; "Common.Controls.Actions.ShareUser" = "Compartir %@"; -"Common.Controls.Actions.SignIn" = "Log in"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignIn" = "Iniciar sesión"; +"Common.Controls.Actions.SignUp" = "Crear cuenta"; "Common.Controls.Actions.Skip" = "Omitir"; "Common.Controls.Actions.TakePhoto" = "Tomar foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Traducir desde %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Desconocido"; "Common.Controls.Actions.TryAgain" = "Inténtalo de nuevo"; "Common.Controls.Actions.UnblockDomain" = "Desbloquear %@"; "Common.Controls.Friendship.Block" = "Bloquear"; @@ -68,13 +74,13 @@ Por favor, revise su conexión a internet."; "Common.Controls.Friendship.EditInfo" = "Editar Info"; "Common.Controls.Friendship.Follow" = "Seguir"; "Common.Controls.Friendship.Following" = "Siguiendo"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.HideReblogs" = "Ocultar reblogs"; "Common.Controls.Friendship.Mute" = "Silenciar"; "Common.Controls.Friendship.MuteUser" = "Silenciar a %@"; "Common.Controls.Friendship.Muted" = "Silenciado"; "Common.Controls.Friendship.Pending" = "Pendiente"; "Common.Controls.Friendship.Request" = "Solicitud"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "Mostrar reblogs"; "Common.Controls.Friendship.Unblock" = "Desbloquear"; "Common.Controls.Friendship.UnblockUser" = "Desbloquear a %@"; "Common.Controls.Friendship.Unmute" = "Desmutear"; @@ -100,6 +106,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Status.Actions.Menu" = "Menú"; "Common.Controls.Status.Actions.Reblog" = "Rebloguear"; "Common.Controls.Status.Actions.Reply" = "Responder"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Compartir enlace en publicación"; "Common.Controls.Status.Actions.ShowGif" = "Mostrar GIF"; "Common.Controls.Status.Actions.ShowImage" = "Mostrar imagen"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Mostrar reproductor de vídeo"; @@ -107,11 +114,13 @@ Por favor, revise su conexión a internet."; "Common.Controls.Status.Actions.Unfavorite" = "No favorito"; "Common.Controls.Status.Actions.Unreblog" = "Deshacer reblogueo"; "Common.Controls.Status.ContentWarning" = "Advertencia de Contenido"; +"Common.Controls.Status.LinkViaUser" = "%@ vía %@"; +"Common.Controls.Status.LoadEmbed" = "Cargar incrustado"; "Common.Controls.Status.MediaContentWarning" = "Pulsa en cualquier sitio para mostrar"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; -"Common.Controls.Status.MetaEntity.Url" = "Link: %@"; +"Common.Controls.Status.MetaEntity.Email" = "Dirección de correo electrónico: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Etiqueta: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Mostrar Perfil: %@"; +"Common.Controls.Status.MetaEntity.Url" = "Enlace: %@"; "Common.Controls.Status.Poll.Closed" = "Cerrado"; "Common.Controls.Status.Poll.Vote" = "Vota"; "Common.Controls.Status.SensitiveContent" = "Contenido sensible"; @@ -124,6 +133,10 @@ Por favor, revise su conexión a internet."; "Common.Controls.Status.Tag.Mention" = "Mención"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tocar para revelar"; +"Common.Controls.Status.Translation.ShowOriginal" = "Mostrar Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Desconocido"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ lo reblogueó"; "Common.Controls.Status.UserRepliedTo" = "En respuesta a %@"; "Common.Controls.Status.Visibility.Direct" = "Sólo el usuario mencionado puede ver este mensaje."; @@ -131,9 +144,9 @@ Por favor, revise su conexión a internet."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Sólo mis seguidores pueden ver este mensaje."; "Common.Controls.Status.Visibility.Unlisted" = "Todo el mundo puede ver este post pero no mostrar en la línea de tiempo pública."; "Common.Controls.Tabs.Home" = "Inicio"; -"Common.Controls.Tabs.Notification" = "Notificación"; +"Common.Controls.Tabs.Notifications" = "Notificaciones"; "Common.Controls.Tabs.Profile" = "Perfil"; -"Common.Controls.Tabs.Search" = "Buscar"; +"Common.Controls.Tabs.SearchAndExplore" = "Buscar y explorar"; "Common.Controls.Timeline.Filtered" = "Filtrado"; "Common.Controls.Timeline.Header.BlockedWarning" = "No puedes ver el perfil de este usuario hasta que te desbloquee."; @@ -155,27 +168,27 @@ Tu perfil se ve así para él."; "Scene.AccountList.AddAccount" = "Añadir cuenta"; "Scene.AccountList.DismissAccountSwitcher" = "Descartar el selector de cuentas"; "Scene.AccountList.TabBarHint" = "Perfil seleccionado actualmente: %@. Haz un doble toque y mantén pulsado para mostrar el selector de cuentas"; -"Scene.Bookmark.Title" = "Bookmarks"; +"Scene.Bookmark.Title" = "Marcadores"; "Scene.Compose.Accessibility.AppendAttachment" = "Añadir Adjunto"; "Scene.Compose.Accessibility.AppendPoll" = "Añadir Encuesta"; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Selector de Emojis Personalizados"; "Scene.Compose.Accessibility.DisableContentWarning" = "Desactivar Advertencia de Contenido"; "Scene.Compose.Accessibility.EnableContentWarning" = "Activar Advertencia de Contenido"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "Opciones de Publicación"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Menú de Visibilidad de la Publicación"; -"Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; +"Scene.Compose.Accessibility.PostingAs" = "Publicado como %@"; "Scene.Compose.Accessibility.RemovePoll" = "Eliminar Encuesta"; "Scene.Compose.Attachment.AttachmentBroken" = "Este %@ está roto y no puede subirse a Mastodon."; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; -"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; -"Scene.Compose.Attachment.CompressingState" = "Compressing..."; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Adjunto demasiado grande"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "No se puede reconocer este archivo adjunto"; +"Scene.Compose.Attachment.CompressingState" = "Comprimiendo..."; "Scene.Compose.Attachment.DescriptionPhoto" = "Describe la foto para los usuarios con dificultad visual..."; "Scene.Compose.Attachment.DescriptionVideo" = "Describe el vídeo para los usuarios con dificultad visual..."; -"Scene.Compose.Attachment.LoadFailed" = "Load Failed"; +"Scene.Compose.Attachment.LoadFailed" = "Carga fallida"; "Scene.Compose.Attachment.Photo" = "foto"; -"Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; +"Scene.Compose.Attachment.ServerProcessingState" = "Procesando en el servidor..."; +"Scene.Compose.Attachment.UploadFailed" = "Error al cargar"; "Scene.Compose.Attachment.Video" = "vídeo"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Espacio para añadir"; "Scene.Compose.ComposeAction" = "Publicar"; @@ -196,8 +209,8 @@ subirse a Mastodon."; "Scene.Compose.Poll.OptionNumber" = "Opción %ld"; "Scene.Compose.Poll.SevenDays" = "7 Días"; "Scene.Compose.Poll.SixHours" = "6 Horas"; -"Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; -"Scene.Compose.Poll.ThePollIsInvalid" = "The poll is invalid"; +"Scene.Compose.Poll.ThePollHasEmptyOption" = "La encuesta tiene una opción vacía"; +"Scene.Compose.Poll.ThePollIsInvalid" = "La encuesta no es válida"; "Scene.Compose.Poll.ThirtyMinutes" = "30 minutos"; "Scene.Compose.Poll.ThreeDays" = "4 Días"; "Scene.Compose.ReplyingToUser" = "en respuesta a %@"; @@ -230,6 +243,12 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Familiarfollowers.Title" = "Seguidores que conoces"; "Scene.Favorite.Title" = "Tus Favoritos"; "Scene.FavoritedBy.Title" = "Hecho favorito por"; +"Scene.FollowedTags.Actions.Follow" = "Seguir"; +"Scene.FollowedTags.Actions.Unfollow" = "Dejar de seguir"; +"Scene.FollowedTags.Header.Participants" = "participantes"; +"Scene.FollowedTags.Header.Posts" = "publicaciones"; +"Scene.FollowedTags.Header.PostsToday" = "publicaciones de hoy"; +"Scene.FollowedTags.Title" = "Etiquetas seguidas"; "Scene.Follower.Footer" = "No se muestran los seguidores de otros servidores."; "Scene.Follower.Title" = "seguidor"; "Scene.Following.Footer" = "No se muestran los seguidos de otros servidores."; @@ -241,9 +260,9 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.HomeTimeline.NavigationBarState.Published" = "¡Publicado!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "Publicación en curso..."; "Scene.HomeTimeline.Title" = "Inicio"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; +"Scene.Login.ServerSearchField.Placeholder" = "Introduzca la URL o busque su servidor"; +"Scene.Login.Subtitle" = "Inicie sesión en el servidor en el que creó su cuenta."; +"Scene.Login.Title" = "Bienvenido de nuevo"; "Scene.Notification.FollowRequest.Accept" = "Aceptar"; "Scene.Notification.FollowRequest.Accepted" = "Aceptado"; "Scene.Notification.FollowRequest.Reject" = "rechazar"; @@ -269,19 +288,20 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Profile.Dashboard.Following" = "siguiendo"; "Scene.Profile.Dashboard.Posts" = "publicaciones"; "Scene.Profile.Fields.AddRow" = "Añadir Fila"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Contenido"; "Scene.Profile.Fields.Placeholder.Label" = "Nombre para el campo"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; -"Scene.Profile.Fields.Verified.Short" = "Verified on %@"; +"Scene.Profile.Fields.Verified.Long" = "La propiedad de este enlace fue verificada el %@"; +"Scene.Profile.Fields.Verified.Short" = "Verificado en %@"; "Scene.Profile.Header.FollowsYou" = "Te sigue"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirmar para bloquear a %@"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloquear cuenta"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirmar para ocultar reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Ocultar reblogs"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirmar para silenciar %@"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Silenciar cuenta"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirmar para mostrar reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Mostrar reblogs"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirmar para desbloquear a %@"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Desbloquear cuenta"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Confirmar para dejar de silenciar a %@"; @@ -405,11 +425,11 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.ServerPicker.EmptyState.BadNetwork" = "Algo ha ido mal al cargar los datos. Comprueba tu conexión a Internet."; "Scene.ServerPicker.EmptyState.FindingServers" = "Encontrando servidores disponibles..."; "Scene.ServerPicker.EmptyState.NoResults" = "Sin resultados"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Buscar comunidades o introducir URL"; "Scene.ServerPicker.Label.Category" = "CATEGORÍA"; "Scene.ServerPicker.Label.Language" = "IDIOMA"; "Scene.ServerPicker.Label.Users" = "USUARIOS"; -"Scene.ServerPicker.Subtitle" = "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers."; +"Scene.ServerPicker.Subtitle" = "Escoge un servidor basado en tu región, intereses o un propósito general. Aún puedes chatear con cualquiera en Mastodon, independientemente de tus servidores."; "Scene.ServerPicker.Title" = "Elige un servidor, cualquier servidor."; "Scene.ServerRules.Button.Confirm" = "Acepto"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict index ca07b6b28..0a904fcfd 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + Quedan %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 carácter other - %ld characters + %ld caracteres plural.count.followed_by_and_mutual diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index e2985112e..882e05ec6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -22,6 +22,9 @@ Egiaztatu Interneteko konexioa."; "Common.Alerts.SignOut.Message" = "Ziur saioa amaitu nahi duzula?"; "Common.Alerts.SignOut.Title" = "Amaitu saioa"; "Common.Alerts.SignUpFailure.Title" = "Hutsegitea izen-ematean"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Inkesta amaitu da"; "Common.Alerts.VoteFailure.Title" = "Hutsegitea botoa ematean"; "Common.Controls.Actions.Add" = "Gehitu"; @@ -31,6 +34,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.Compose" = "Idatzi"; "Common.Controls.Actions.Confirm" = "Berretsi"; "Common.Controls.Actions.Continue" = "Jarraitu"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Kopiatu argazkia"; "Common.Controls.Actions.Delete" = "Ezabatu"; "Common.Controls.Actions.Discard" = "Baztertu"; @@ -55,10 +59,12 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.Share" = "Partekatu"; "Common.Controls.Actions.SharePost" = "Partekatu bidalketa"; "Common.Controls.Actions.ShareUser" = "Partekatu %@"; -"Common.Controls.Actions.SignIn" = "Log in"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignIn" = "Hasi saioa"; +"Common.Controls.Actions.SignUp" = "Sortu kontua"; "Common.Controls.Actions.Skip" = "Saltatu"; "Common.Controls.Actions.TakePhoto" = "Atera argazkia"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Saiatu berriro"; "Common.Controls.Actions.UnblockDomain" = "Desblokeatu %@"; "Common.Controls.Friendship.Block" = "Blokeatu"; @@ -68,13 +74,13 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Friendship.EditInfo" = "Editatu informazioa"; "Common.Controls.Friendship.Follow" = "Jarraitu"; "Common.Controls.Friendship.Following" = "Jarraitzen"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.HideReblogs" = "Ezkutatu bultzadak"; "Common.Controls.Friendship.Mute" = "Mututu"; "Common.Controls.Friendship.MuteUser" = "Mututu %@"; "Common.Controls.Friendship.Muted" = "Mutututa"; "Common.Controls.Friendship.Pending" = "Zain"; "Common.Controls.Friendship.Request" = "Eskaera"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "Ikusi bultzadak"; "Common.Controls.Friendship.Unblock" = "Desblokeatu"; "Common.Controls.Friendship.UnblockUser" = "Desblokeatu %@"; "Common.Controls.Friendship.Unmute" = "Desmututu"; @@ -100,6 +106,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Status.Actions.Menu" = "Menua"; "Common.Controls.Status.Actions.Reblog" = "Bultzada"; "Common.Controls.Status.Actions.Reply" = "Erantzun"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Erakutsi GIFa"; "Common.Controls.Status.Actions.ShowImage" = "Erakutsi irudia"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Erakutsi bideo-erreproduzigailua"; @@ -107,14 +114,16 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Status.Actions.Unfavorite" = "Kendu gogokoa"; "Common.Controls.Status.Actions.Unreblog" = "Desegin bultzada"; "Common.Controls.Status.ContentWarning" = "Edukiaren abisua"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Ukitu edonon bistaratzeko"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; -"Common.Controls.Status.MetaEntity.Url" = "Link: %@"; +"Common.Controls.Status.MetaEntity.Email" = "E-posta helbidea: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Traolak: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Erakutsi Profila: %@"; +"Common.Controls.Status.MetaEntity.Url" = "Lotura: %@"; "Common.Controls.Status.Poll.Closed" = "Itxita"; "Common.Controls.Status.Poll.Vote" = "Bozkatu"; -"Common.Controls.Status.SensitiveContent" = "Sensitive Content"; +"Common.Controls.Status.SensitiveContent" = "Eduki hunkigarria"; "Common.Controls.Status.ShowPost" = "Erakutsi bidalketa"; "Common.Controls.Status.ShowUserProfile" = "Erakutsi erabiltzailearen profila"; "Common.Controls.Status.Tag.Email" = "Eposta"; @@ -124,6 +133,10 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Status.Tag.Mention" = "Aipatu"; "Common.Controls.Status.Tag.Url" = "URLa"; "Common.Controls.Status.TapToReveal" = "Sakatu erakusteko"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ erabiltzaileak bultzada eman dio"; "Common.Controls.Status.UserRepliedTo" = "%@(r)i erantzuten"; "Common.Controls.Status.Visibility.Direct" = "Aipatutako erabiltzaileek soilik ikus dezakete bidalketa hau."; @@ -131,9 +144,9 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Nire jarraitzaileek soilik ikus dezakete bidalketa hau."; "Common.Controls.Status.Visibility.Unlisted" = "Edozeinek ikusi dezake bidalketa hau baina ez da denbora-lerro publikoan bistaratuko."; "Common.Controls.Tabs.Home" = "Hasiera"; -"Common.Controls.Tabs.Notification" = "Jakinarazpena"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profila"; -"Common.Controls.Tabs.Search" = "Bilatu"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Iragazita"; "Common.Controls.Timeline.Header.BlockedWarning" = "Ezin duzu erabiltzaile honen profila ikusi desblokeatzen zaituen arte."; @@ -155,27 +168,27 @@ Zure profilak itxura hau du berarentzat."; "Scene.AccountList.AddAccount" = "Gehitu kontua"; "Scene.AccountList.DismissAccountSwitcher" = "Baztertu kontu-aldatzailea"; "Scene.AccountList.TabBarHint" = "Unean hautatutako profila: %@. Ukitu birritan, ondoren eduki sakatuta kontu-aldatzailea erakusteko"; -"Scene.Bookmark.Title" = "Bookmarks"; +"Scene.Bookmark.Title" = "Laster-markak"; "Scene.Compose.Accessibility.AppendAttachment" = "Gehitu eranskina"; "Scene.Compose.Accessibility.AppendPoll" = "Gehitu inkesta"; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Emoji pertsonalizatuen hautatzailea"; "Scene.Compose.Accessibility.DisableContentWarning" = "Desgaitu edukiaren abisua"; "Scene.Compose.Accessibility.EnableContentWarning" = "Gaitu edukiaren abisua"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "Bildalketaren aukerak"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Bidalketaren ikusgaitasunaren menua"; "Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; "Scene.Compose.Accessibility.RemovePoll" = "Kendu inkesta"; "Scene.Compose.Attachment.AttachmentBroken" = "%@ hondatuta dago eta ezin da Mastodonera igo."; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Eranskina handiegia da"; "Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; -"Scene.Compose.Attachment.CompressingState" = "Compressing..."; +"Scene.Compose.Attachment.CompressingState" = "Konprimatzen..."; "Scene.Compose.Attachment.DescriptionPhoto" = "Deskribatu argazkia ikusmen arazoak dituztenentzat..."; "Scene.Compose.Attachment.DescriptionVideo" = "Deskribatu bideoa ikusmen arazoak dituztenentzat..."; "Scene.Compose.Attachment.LoadFailed" = "Load Failed"; "Scene.Compose.Attachment.Photo" = "argazkia"; "Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; +"Scene.Compose.Attachment.UploadFailed" = "Kargatzeak huts egin du"; "Scene.Compose.Attachment.Video" = "bideoa"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Sakatu zuriunea gehitzeko"; "Scene.Compose.ComposeAction" = "Argitaratu"; @@ -197,7 +210,7 @@ Mastodonera igo."; "Scene.Compose.Poll.SevenDays" = "7 egun"; "Scene.Compose.Poll.SixHours" = "6 ordu"; "Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; -"Scene.Compose.Poll.ThePollIsInvalid" = "The poll is invalid"; +"Scene.Compose.Poll.ThePollIsInvalid" = "Inkesta ez da balekoa"; "Scene.Compose.Poll.ThirtyMinutes" = "30 minutu"; "Scene.Compose.Poll.ThreeDays" = "3 egun"; "Scene.Compose.ReplyingToUser" = "%@(r)i erantzuten"; @@ -217,10 +230,10 @@ Mastodonera igo."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Ireki eposta bezeroa"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Egiaztatu zure sarrerako ontzia."; "Scene.ConfirmEmail.Subtitle" = "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko."; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko"; "Scene.ConfirmEmail.Title" = "Eta azkenik..."; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Intro" = "Hauek dira zure Mastodon txokoan beraien lekua hartzen ari diren argitalpenak."; +"Scene.Discovery.Tabs.Community" = "Komunitatea"; "Scene.Discovery.Tabs.ForYou" = "Zuretzat"; "Scene.Discovery.Tabs.Hashtags" = "Traolak"; "Scene.Discovery.Tabs.News" = "Albisteak"; @@ -229,12 +242,18 @@ Mastodonera igo."; "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Zure gogokoak"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Beste zerbitzarietako jarraitzaileak ez dira bistaratzen."; -"Scene.Follower.Title" = "follower"; +"Scene.Follower.Title" = "jarraitzaile"; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; -"Scene.Following.Title" = "following"; +"Scene.Following.Title" = "jarraitzen"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo botoia"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; @@ -242,11 +261,11 @@ Mastodonera igo."; "Scene.HomeTimeline.Title" = "Hasiera"; "Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; "Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; -"Scene.Notification.FollowRequest.Accept" = "Accept"; -"Scene.Notification.FollowRequest.Accepted" = "Accepted"; -"Scene.Notification.FollowRequest.Reject" = "reject"; -"Scene.Notification.FollowRequest.Rejected" = "Rejected"; +"Scene.Login.Title" = "Ongi etorri berriro ere"; +"Scene.Notification.FollowRequest.Accept" = "Onartu"; +"Scene.Notification.FollowRequest.Accepted" = "Onartuta"; +"Scene.Notification.FollowRequest.Reject" = "ukatu"; +"Scene.Notification.FollowRequest.Rejected" = "Ukatua"; "Scene.Notification.Keyobard.ShowEverything" = "Erakutsi guztia"; "Scene.Notification.Keyobard.ShowMentions" = "Erakutsi aipamenak"; "Scene.Notification.NotificationDescription.FavoritedYourPost" = "(e)k zure bidalketa gogoko du"; @@ -268,19 +287,20 @@ Mastodonera igo."; "Scene.Profile.Dashboard.Following" = "jarraitzen"; "Scene.Profile.Dashboard.Posts" = "bidalketa"; "Scene.Profile.Fields.AddRow" = "Gehitu errenkada"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Edukia"; "Scene.Profile.Fields.Placeholder.Label" = "Etiketa"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; +"Scene.Profile.Fields.Verified.Long" = "Esteka honen jabetzaren egiaztaketa data: %@"; "Scene.Profile.Fields.Verified.Short" = "Verified on %@"; -"Scene.Profile.Header.FollowsYou" = "Follows You"; +"Scene.Profile.Header.FollowsYou" = "Jarraitzen zaitu"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Berretsi %@ blokeatzea"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blokeatu kontua"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Berretsi birbidalketak ezkutatzea"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Ezkutatu bultzadak"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Berretsi %@ mututzea"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Mututu kontua"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Berretsi birbidalketak ikustea"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Ikusi bultzadak"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Berretsi %@ desblokeatzea"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Desblokeatu kontua"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Berretsi %@ desmututzea"; @@ -323,7 +343,7 @@ Mastodonera igo."; "Scene.Register.Input.Password.Require" = "Zure pasahitzak izan behar ditu gutxienez:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Erabiltzaile-izen hau hartuta dago."; "Scene.Register.Input.Username.Placeholder" = "erabiltzaile-izena"; -"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "%@ zerbitzariko kontua prestatuko dizugu"; "Scene.Register.Title" = "Hitz egin iezaguzu zuri buruz."; "Scene.Report.Content1" = "Salaketan beste bidalketarik gehitu nahi duzu?"; "Scene.Report.Content2" = "Moderatzaileek besterik jakin behar dute salaketa honi buruz?"; @@ -333,38 +353,38 @@ Mastodonera igo."; "Scene.Report.SkipToSend" = "Bidali iruzkinik gabe"; "Scene.Report.Step1" = "1. urratsa 2tik"; "Scene.Report.Step2" = "2. urratsa 2tik"; -"Scene.Report.StepFinal.BlockUser" = "Block %@"; -"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; -"Scene.Report.StepFinal.MuteUser" = "Mute %@"; -"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; -"Scene.Report.StepFinal.Unfollow" = "Unfollow"; -"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.BlockUser" = "Blokeatu %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Ez duzu hau ikusi nahi?"; +"Scene.Report.StepFinal.MuteUser" = "Mututu %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Ezin izango dituzte zure bidalketak jarraitu edo ikusi, baina blokeatuta dauden ikusi ahal izango dute."; +"Scene.Report.StepFinal.Unfollow" = "Utzi jarraitzeari"; +"Scene.Report.StepFinal.UnfollowUser" = "%@ jarraitzeari utzi"; "Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; -"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; -"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; -"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; -"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; -"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; -"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; -"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; -"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; -"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; -"Scene.Report.StepOne.ItsSpam" = "It’s spam"; -"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; -"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; -"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; -"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; -"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; -"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; -"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; -"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; -"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; -"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; -"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Mastodonen gustuko ez duzun zerbait ikusten duzunean, zure esperientziatik atera dezakezu pertsona hori."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Hau berrikusten dugun bitartean, %@ erabiltzailearen aurkako neurriak hartu ditzakezu"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Ez dituzu bere bidalketa eta birbidalketak zure hasierako jarioan ikusiko. Ez dute jakingo isilarazi dituztenik."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Beste zerbait jakin beharko genuke?"; +"Scene.Report.StepFour.Step4Of4" = "4. urratsa 4tik"; +"Scene.Report.StepOne.IDontLikeIt" = "Ez dut gustukoa"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Ikusi nahi ez dudan zerbait da"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Zerbitzariaren arauak hausten ditu"; +"Scene.Report.StepOne.ItsSomethingElse" = "Beste zerbait da"; +"Scene.Report.StepOne.ItsSpam" = "Spama da"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Esteka maltzurrak, gezurrezko elkarrekintzak edo erantzun errepikakorrak"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Aukeratu egokiena"; +"Scene.Report.StepOne.Step1Of4" = "1. urratsa 4tik"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Arazoa ezin da beste kategorietan sailkatu"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Zer du txarra kontu honek?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Zer du txarra argitalpen honek?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Zer du txarra %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Arau zehatzak urratzen dituela badakizu"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Salaketa hau babesten duen bidalketarik badago?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Hautatu dagozkion guztiak"; +"Scene.Report.StepThree.Step3Of4" = "3. urratsa 4tik"; "Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; -"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; -"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; -"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Hautatu dagozkion guztiak"; +"Scene.Report.StepTwo.Step2Of4" = "2. urratsa 4tik"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Ze arau hautsi ditu?"; "Scene.Report.TextPlaceholder" = "Idatzi edo itsatsi iruzkin gehigarriak"; "Scene.Report.Title" = "Salatu %@"; "Scene.Report.TitleReport" = "Salatu"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict index 057ca4010..404deebd3 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict @@ -63,13 +63,13 @@ one 1 character other - %ld characters + %ld karaktere plural.count.followed_by_and_mutual NSStringLocalizedFormatKey - %#@names@%#@count_mutual@ + %#@names@: "%#@count_mutual@ names one diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index 7902fb6eb..de4bf3101 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -22,6 +22,9 @@ Tarkista internet-yhteytesi."; "Common.Alerts.SignOut.Message" = "Haluatko varmasti kirjautua ulos?"; "Common.Alerts.SignOut.Title" = "Kirjaudu ulos"; "Common.Alerts.SignUpFailure.Title" = "Rekisteröinti epäonnistui"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Kysely on päättynyt"; "Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Lisää"; @@ -31,6 +34,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Compose" = "Koosta"; "Common.Controls.Actions.Confirm" = "Vahvista"; "Common.Controls.Actions.Continue" = "Jatka"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Kopioi kuva"; "Common.Controls.Actions.Delete" = "Poista"; "Common.Controls.Actions.Discard" = "Hylkää"; @@ -59,6 +63,8 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Ohita"; "Common.Controls.Actions.TakePhoto" = "Ota kuva"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Yritä uudelleen"; "Common.Controls.Actions.UnblockDomain" = "Poista esto %@"; "Common.Controls.Friendship.Block" = "Estä"; @@ -100,6 +106,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Status.Actions.Menu" = "Valikko"; "Common.Controls.Status.Actions.Reblog" = "Jaa edelleen"; "Common.Controls.Status.Actions.Reply" = "Vastaa"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Show GIF"; "Common.Controls.Status.Actions.ShowImage" = "Show image"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; @@ -107,6 +114,8 @@ Tarkista internet-yhteytesi."; "Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; "Common.Controls.Status.Actions.Unreblog" = "Peru edelleen jako"; "Common.Controls.Status.ContentWarning" = "Sisältövaroitus"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Napauta mistä tahansa paljastaaksesi"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ Tarkista internet-yhteytesi."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tap to reveal"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ jakoi edelleen"; "Common.Controls.Status.UserRepliedTo" = "Vastasi %@:lle"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; @@ -131,9 +144,9 @@ Tarkista internet-yhteytesi."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; "Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Koti"; -"Common.Controls.Tabs.Notification" = "Ilmoitus"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profiili"; -"Common.Controls.Tabs.Search" = "Haku"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Suodatettu"; "Common.Controls.Timeline.Header.BlockedWarning" = "Et voi tarkastella tämän tilin profiilia ennen kuin hän poistaa eston."; @@ -229,6 +242,12 @@ uploaded to Mastodon."; "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Omat suosikit"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Seuraajia muilta palvelimilta ei näytetä."; "Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; @@ -268,6 +287,7 @@ uploaded to Mastodon."; "Scene.Profile.Dashboard.Following" = "seurataan"; "Scene.Profile.Dashboard.Posts" = "julkaisut"; "Scene.Profile.Fields.AddRow" = "Lisää rivi"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Sisältö"; "Scene.Profile.Fields.Placeholder.Label" = "Nimi"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index f393adec1..0bc619b34 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -22,6 +22,9 @@ Veuillez vérifier votre accès à Internet."; "Common.Alerts.SignOut.Message" = "Voulez-vous vraiment vous déconnecter ?"; "Common.Alerts.SignOut.Title" = "Se déconnecter"; "Common.Alerts.SignUpFailure.Title" = "Échec de l'inscription"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "La traduction a échoué. Peut-être que l'administrateur n'a pas activé les traductions sur ce serveur ou que ce serveur utilise une ancienne version de Mastodon où les traductions ne sont pas encore prises en charge."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Le sondage est terminé"; "Common.Alerts.VoteFailure.Title" = "Échec du vote"; "Common.Controls.Actions.Add" = "Ajouter"; @@ -31,6 +34,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Compose" = "Rédiger"; "Common.Controls.Actions.Confirm" = "Confirmer"; "Common.Controls.Actions.Continue" = "Continuer"; +"Common.Controls.Actions.Copy" = "Copier"; "Common.Controls.Actions.CopyPhoto" = "Copier la photo"; "Common.Controls.Actions.Delete" = "Supprimer"; "Common.Controls.Actions.Discard" = "Abandonner"; @@ -59,6 +63,8 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.SignUp" = "Créer un compte"; "Common.Controls.Actions.Skip" = "Passer"; "Common.Controls.Actions.TakePhoto" = "Prendre une photo"; +"Common.Controls.Actions.TranslatePost.Title" = "Traduit depuis %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Inconnu"; "Common.Controls.Actions.TryAgain" = "Réessayer"; "Common.Controls.Actions.UnblockDomain" = "Débloquer %@"; "Common.Controls.Friendship.Block" = "Bloquer"; @@ -100,6 +106,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Actions.Menu" = "Menu"; "Common.Controls.Status.Actions.Reblog" = "Rebloguer"; "Common.Controls.Status.Actions.Reply" = "Répondre"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Partager le lien dans le message"; "Common.Controls.Status.Actions.ShowGif" = "Afficher le GIF"; "Common.Controls.Status.Actions.ShowImage" = "Afficher l’image"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Afficher le lecteur vidéo"; @@ -107,6 +114,8 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Actions.Unfavorite" = "Retirer des favoris"; "Common.Controls.Status.Actions.Unreblog" = "Annuler le reblog"; "Common.Controls.Status.ContentWarning" = "Avertissement de contenu"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Charger l'intégration"; "Common.Controls.Status.MediaContentWarning" = "Tapotez n’importe où pour révéler la publication"; "Common.Controls.Status.MetaEntity.Email" = "Adresse e-mail : %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag : %@"; @@ -124,6 +133,10 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Appuyer pour afficher"; +"Common.Controls.Status.Translation.ShowOriginal" = "Afficher l’original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Inconnu"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ a reblogué"; "Common.Controls.Status.UserRepliedTo" = "À répondu à %@"; "Common.Controls.Status.Visibility.Direct" = "Seul·e l’utilisateur·rice mentionnée peut voir ce message."; @@ -131,9 +144,9 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Seul·e·s mes abonné·e·s peuvent voir ce message."; "Common.Controls.Status.Visibility.Unlisted" = "Tout le monde peut voir ce message mais ne sera pas affiché sur le fil public."; "Common.Controls.Tabs.Home" = "Accueil"; -"Common.Controls.Tabs.Notification" = "Notification"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Rechercher"; +"Common.Controls.Tabs.SearchAndExplore" = "Rechercher et explorer"; "Common.Controls.Timeline.Filtered" = "Filtré"; "Common.Controls.Timeline.Header.BlockedWarning" = "Vous ne pouvez pas voir le profil de cet utilisateur tant qu'il ne vous aura pas débloqué."; @@ -229,6 +242,12 @@ téléversé sur Mastodon."; "Scene.Familiarfollowers.Title" = "Abonné·e·s que vous connaissez"; "Scene.Favorite.Title" = "Vos favoris"; "Scene.FavoritedBy.Title" = "Favoris par"; +"Scene.FollowedTags.Actions.Follow" = "Suivre"; +"Scene.FollowedTags.Actions.Unfollow" = "Ne plus suivre"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "messages"; +"Scene.FollowedTags.Header.PostsToday" = "messages aujourd'hui"; +"Scene.FollowedTags.Title" = "Tags suivis"; "Scene.Follower.Footer" = "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s."; "Scene.Follower.Title" = "abonné·e"; "Scene.Following.Footer" = "Les abonnés issus des autres serveurs ne sont pas affichés."; @@ -268,6 +287,7 @@ téléversé sur Mastodon."; "Scene.Profile.Dashboard.Following" = "abonnements"; "Scene.Profile.Dashboard.Posts" = "publications"; "Scene.Profile.Fields.AddRow" = "Ajouter une rangée"; +"Scene.Profile.Fields.Joined" = "Ici depuis"; "Scene.Profile.Fields.Placeholder.Content" = "Contenu"; "Scene.Profile.Fields.Placeholder.Label" = "Étiquette"; "Scene.Profile.Fields.Verified.Long" = "La propriété de ce lien a été vérifiée le %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index 6ccf6cf15..e37be3344 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -22,6 +22,9 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Alerts.SignOut.Message" = "A bheil thu cinnteach gu bheil thu airson clàradh a-mach?"; "Common.Alerts.SignOut.Title" = "Clàraich a-mach"; "Common.Alerts.SignUpFailure.Title" = "Dh’fhàillig leis a’ chlàradh"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Thàinig an cunntas-bheachd gu crìoch"; "Common.Alerts.VoteFailure.Title" = "Dh’fhàillig leis a’ bhòt"; "Common.Controls.Actions.Add" = "Cuir ris"; @@ -31,6 +34,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Compose" = "Sgrìobh"; "Common.Controls.Actions.Confirm" = "Dearbh"; "Common.Controls.Actions.Continue" = "Lean air adhart"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Dèan lethbhreac dhen dealbh"; "Common.Controls.Actions.Delete" = "Sguab às"; "Common.Controls.Actions.Discard" = "Tilg air falbh"; @@ -59,6 +63,8 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.SignUp" = "Cruthaich cunntas"; "Common.Controls.Actions.Skip" = "Leum thairis air"; "Common.Controls.Actions.TakePhoto" = "Tog dealbh"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Feuch ris a-rithist"; "Common.Controls.Actions.UnblockDomain" = "Dì-bhac %@"; "Common.Controls.Friendship.Block" = "Bac"; @@ -100,6 +106,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Status.Actions.Menu" = "Clàr-taice"; "Common.Controls.Status.Actions.Reblog" = "Brosnaich"; "Common.Controls.Status.Actions.Reply" = "Freagair"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Seall an GIF"; "Common.Controls.Status.Actions.ShowImage" = "Seall an dealbh"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Seall cluicheadair video"; @@ -107,6 +114,8 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Status.Actions.Unfavorite" = "Thoir air falbh o na h-annsachdan"; "Common.Controls.Status.Actions.Unreblog" = "Na brosnaich tuilleadh"; "Common.Controls.Status.ContentWarning" = "Rabhadh susbainte"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Thoir gnogag àite sam bith gus a nochdadh"; "Common.Controls.Status.MetaEntity.Email" = "Seòladh puist-d: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Taga hais: %@"; @@ -124,6 +133,10 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Status.Tag.Mention" = "Iomradh"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Thoir gnogag gus a nochdadh"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "Tha %@ ’ga bhrosnachadh"; "Common.Controls.Status.UserRepliedTo" = "Air %@ fhreagairt"; "Common.Controls.Status.Visibility.Direct" = "Chan fhaic ach an cleachdaiche air an dugadh iomradh am post seo."; @@ -131,9 +144,9 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Chan fhaic ach an luchd-leantainn agam am post seo."; "Common.Controls.Status.Visibility.Unlisted" = "Chì a h-uile duine am post seo ach cha nochd e air an loidhne-ama phoblach."; "Common.Controls.Tabs.Home" = "Dachaigh"; -"Common.Controls.Tabs.Notification" = "Brath"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Pròifil"; -"Common.Controls.Tabs.Search" = "Lorg"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Criathraichte"; "Common.Controls.Timeline.Header.BlockedWarning" = "Chan fhaic thu pròifil a’ chleachdaiche seo mus dì-bhac iad thu."; @@ -229,6 +242,12 @@ a luchdadh suas gu Mastodon."; "Scene.Familiarfollowers.Title" = "Luchd-leantainn aithnichte"; "Scene.Favorite.Title" = "Na h-annsachdan agad"; "Scene.FavoritedBy.Title" = "’Na annsachd aig"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Cha dèid luchd-leantainn o fhrithealaichean eile a shealltainn."; "Scene.Follower.Title" = "neach-leantainn"; "Scene.Following.Footer" = "Cha dèid cò a leanas tu air frithealaichean eile a shealltainn."; @@ -268,6 +287,7 @@ a luchdadh suas gu Mastodon."; "Scene.Profile.Dashboard.Following" = "a’ leantainn"; "Scene.Profile.Dashboard.Posts" = "postaichean"; "Scene.Profile.Fields.AddRow" = "Cuir ràgh ris"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Susbaint"; "Scene.Profile.Fields.Placeholder.Label" = "Leubail"; "Scene.Profile.Fields.Verified.Long" = "Chaidh dearbhadh cò leis a tha an ceangal seo %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index f9e1c6589..35a465661 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -22,6 +22,9 @@ Comproba a conexión a internet."; "Common.Alerts.SignOut.Message" = "Tes a certeza de queres pechar a sesión?"; "Common.Alerts.SignOut.Title" = "Pechar sesión"; "Common.Alerts.SignUpFailure.Title" = "Fallou o rexistro"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Fallou a tradución. É posible que a administración non activase a tradución neste servidor ou que o servidor teña unha versión antiga de Mastodon que non ten soporte para a tradución."; +"Common.Alerts.TranslationFailed.Title" = "Nota"; "Common.Alerts.VoteFailure.PollEnded" = "A enquisa rematou"; "Common.Alerts.VoteFailure.Title" = "Fallou a votación"; "Common.Controls.Actions.Add" = "Engadir"; @@ -31,6 +34,7 @@ Comproba a conexión a internet."; "Common.Controls.Actions.Compose" = "Escribir"; "Common.Controls.Actions.Confirm" = "Confirmar"; "Common.Controls.Actions.Continue" = "Continuar"; +"Common.Controls.Actions.Copy" = "Copiar"; "Common.Controls.Actions.CopyPhoto" = "Copiar foto"; "Common.Controls.Actions.Delete" = "Eliminar"; "Common.Controls.Actions.Discard" = "Descartar"; @@ -59,6 +63,8 @@ Comproba a conexión a internet."; "Common.Controls.Actions.SignUp" = "Crear conta"; "Common.Controls.Actions.Skip" = "Omitir"; "Common.Controls.Actions.TakePhoto" = "Facer foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Traducido do %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Descoñecido"; "Common.Controls.Actions.TryAgain" = "Intentar de novo"; "Common.Controls.Actions.UnblockDomain" = "Desbloquear a %@"; "Common.Controls.Friendship.Block" = "Bloquear"; @@ -100,6 +106,7 @@ Comproba a conexión a internet."; "Common.Controls.Status.Actions.Menu" = "Menú"; "Common.Controls.Status.Actions.Reblog" = "Promover"; "Common.Controls.Status.Actions.Reply" = "Responder"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Compartir Ligazón na Publicación"; "Common.Controls.Status.Actions.ShowGif" = "Mostrar GIF"; "Common.Controls.Status.Actions.ShowImage" = "Mostrar a imaxe"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Mostrar reprodutor de vídeo"; @@ -107,6 +114,8 @@ Comproba a conexión a internet."; "Common.Controls.Status.Actions.Unfavorite" = "Eliminar dos favoritos"; "Common.Controls.Status.Actions.Unreblog" = "Retirar promoción"; "Common.Controls.Status.ContentWarning" = "Aviso sobre o contido"; +"Common.Controls.Status.LinkViaUser" = "%@ vía %@"; +"Common.Controls.Status.LoadEmbed" = "Cargar o contido"; "Common.Controls.Status.MediaContentWarning" = "Toca nalgures para mostrar"; "Common.Controls.Status.MetaEntity.Email" = "Enderezo de email: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Cancelo: %@"; @@ -124,6 +133,10 @@ Comproba a conexión a internet."; "Common.Controls.Status.Tag.Mention" = "Mención"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Toca para mostrar"; +"Common.Controls.Status.Translation.ShowOriginal" = "Mostrar o orixinal"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Descoñecido"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ promoveu"; "Common.Controls.Status.UserRepliedTo" = "Respondeu a %@"; "Common.Controls.Status.Visibility.Direct" = "Só a usuaria mencionada pode ver a publicación."; @@ -131,9 +144,9 @@ Comproba a conexión a internet."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Só as miñas seguidoras poden ver esta publicación."; "Common.Controls.Status.Visibility.Unlisted" = "A publicación é visible para calquera pero non aparece na cronoloxía pública."; "Common.Controls.Tabs.Home" = "Inicio"; -"Common.Controls.Tabs.Notification" = "Notificación"; +"Common.Controls.Tabs.Notifications" = "Notificacións"; "Common.Controls.Tabs.Profile" = "Perfil"; -"Common.Controls.Tabs.Search" = "Busca"; +"Common.Controls.Tabs.SearchAndExplore" = "Buscar e Explorar"; "Common.Controls.Timeline.Filtered" = "Filtrado"; "Common.Controls.Timeline.Header.BlockedWarning" = "Non podes ver o perfil desta usuaria ata que te desbloquee."; @@ -229,6 +242,12 @@ ser subido a Mastodon."; "Scene.Familiarfollowers.Title" = "Seguimentos próximos"; "Scene.Favorite.Title" = "Publicacións Favoritas"; "Scene.FavoritedBy.Title" = "Favorecido por"; +"Scene.FollowedTags.Actions.Follow" = "Seguir"; +"Scene.FollowedTags.Actions.Unfollow" = "Deixar de seguir"; +"Scene.FollowedTags.Header.Participants" = "participantes"; +"Scene.FollowedTags.Header.Posts" = "publicacións"; +"Scene.FollowedTags.Header.PostsToday" = "publicacións de hoxe"; +"Scene.FollowedTags.Title" = "Cancelos seguidos"; "Scene.Follower.Footer" = "Non se mostran seguidoras desde outros servidores."; "Scene.Follower.Title" = "seguidora"; "Scene.Following.Footer" = "Non se mostran os seguimentos desde outros servidores."; @@ -268,6 +287,7 @@ ser subido a Mastodon."; "Scene.Profile.Dashboard.Following" = "seguindo"; "Scene.Profile.Dashboard.Posts" = "publicacións"; "Scene.Profile.Fields.AddRow" = "Engadir fila"; +"Scene.Profile.Fields.Joined" = "Uniuse"; "Scene.Profile.Fields.Placeholder.Content" = "Contido"; "Scene.Profile.Fields.Placeholder.Label" = "Etiqueta"; "Scene.Profile.Fields.Verified.Long" = "A propiedade desta ligazón foi verificada o %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index fab67c38d..96af84e22 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -22,6 +22,9 @@ Per favore verifica la tua connessione internet."; "Common.Alerts.SignOut.Message" = "Vuoi davvero scollegarti?"; "Common.Alerts.SignOut.Title" = "Esci"; "Common.Alerts.SignUpFailure.Title" = "Iscrizione fallita"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Traduzione fallita. Forse l'amministratore non ha abilitato le traduzioni su questo server o questo server sta eseguendo una versione precedente di Mastodon in cui le traduzioni non sono ancora supportate."; +"Common.Alerts.TranslationFailed.Title" = "Nota"; "Common.Alerts.VoteFailure.PollEnded" = "Il sondaggio è terminato"; "Common.Alerts.VoteFailure.Title" = "Voto fallito"; "Common.Controls.Actions.Add" = "Aggiungi"; @@ -31,6 +34,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.Compose" = "Scrivi"; "Common.Controls.Actions.Confirm" = "Conferma"; "Common.Controls.Actions.Continue" = "Continua"; +"Common.Controls.Actions.Copy" = "Copia"; "Common.Controls.Actions.CopyPhoto" = "Copia foto"; "Common.Controls.Actions.Delete" = "Elimina"; "Common.Controls.Actions.Discard" = "Abbandona"; @@ -59,6 +63,8 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.SignUp" = "Crea un account"; "Common.Controls.Actions.Skip" = "Salta"; "Common.Controls.Actions.TakePhoto" = "Scatta foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Traduci da %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Sconosciuto"; "Common.Controls.Actions.TryAgain" = "Riprova"; "Common.Controls.Actions.UnblockDomain" = "Sblocca %@"; "Common.Controls.Friendship.Block" = "Blocca"; @@ -100,6 +106,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Status.Actions.Menu" = "Menù"; "Common.Controls.Status.Actions.Reblog" = "Condivisione"; "Common.Controls.Status.Actions.Reply" = "Rispondi"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Condividi il collegamento nel post"; "Common.Controls.Status.Actions.ShowGif" = "Mostra GIF"; "Common.Controls.Status.Actions.ShowImage" = "Mostra immagine"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Mostra lettore video"; @@ -107,6 +114,8 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Status.Actions.Unfavorite" = "Non preferito"; "Common.Controls.Status.Actions.Unreblog" = "Annulla condivisione"; "Common.Controls.Status.ContentWarning" = "Avviso sul contenuto"; +"Common.Controls.Status.LinkViaUser" = "%@ tramite %@"; +"Common.Controls.Status.LoadEmbed" = "Carica Incorpora"; "Common.Controls.Status.MediaContentWarning" = "Tocca ovunque per rivelare"; "Common.Controls.Status.MetaEntity.Email" = "Indirizzo email: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -119,11 +128,15 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Status.ShowUserProfile" = "Mostra il profilo dell'utente"; "Common.Controls.Status.Tag.Email" = "Email"; "Common.Controls.Status.Tag.Emoji" = "Emoji"; -"Common.Controls.Status.Tag.Hashtag" = "Etichetta"; +"Common.Controls.Status.Tag.Hashtag" = "Hashtag"; "Common.Controls.Status.Tag.Link" = "Collegamento"; "Common.Controls.Status.Tag.Mention" = "Menzione"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tocca per rivelare"; +"Common.Controls.Status.Translation.ShowOriginal" = "Mostra l'originale"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Sconosciuto"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ ha condiviso"; "Common.Controls.Status.UserRepliedTo" = "Risposta a %@"; "Common.Controls.Status.Visibility.Direct" = "Solo l'utente menzionato può vedere questo post."; @@ -131,9 +144,9 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Solo i miei seguaci possono vedere questo post."; "Common.Controls.Status.Visibility.Unlisted" = "Tutti possono vedere questo post ma non mostrare nella cronologia pubblica."; "Common.Controls.Tabs.Home" = "Inizio"; -"Common.Controls.Tabs.Notification" = "Notifiche"; +"Common.Controls.Tabs.Notifications" = "Notifiche"; "Common.Controls.Tabs.Profile" = "Profilo"; -"Common.Controls.Tabs.Search" = "Cerca"; +"Common.Controls.Tabs.SearchAndExplore" = "Cerca ed Esplora"; "Common.Controls.Timeline.Filtered" = "Filtrato"; "Common.Controls.Timeline.Header.BlockedWarning" = "Non puoi visualizzare il profilo di questo utente fino a quando non ti sbloccano."; @@ -229,6 +242,12 @@ caricato su Mastodon."; "Scene.Familiarfollowers.Title" = "Seguaci che conosci"; "Scene.Favorite.Title" = "I tuoi preferiti"; "Scene.FavoritedBy.Title" = "Preferito Da"; +"Scene.FollowedTags.Actions.Follow" = "Segui"; +"Scene.FollowedTags.Actions.Unfollow" = "Smetti di seguire"; +"Scene.FollowedTags.Header.Participants" = "partecipanti"; +"Scene.FollowedTags.Header.Posts" = "post"; +"Scene.FollowedTags.Header.PostsToday" = "post di oggi"; +"Scene.FollowedTags.Title" = "Etichette seguite"; "Scene.Follower.Footer" = "I seguaci da altri server non vengono visualizzati."; "Scene.Follower.Title" = "seguace"; "Scene.Following.Footer" = "I follow da altri server non vengono visualizzati."; @@ -268,6 +287,7 @@ caricato su Mastodon."; "Scene.Profile.Dashboard.Following" = "seguendo"; "Scene.Profile.Dashboard.Posts" = "post"; "Scene.Profile.Fields.AddRow" = "Aggiungi riga"; +"Scene.Profile.Fields.Joined" = "Profilo iscritto"; "Scene.Profile.Fields.Placeholder.Content" = "Contenuto"; "Scene.Profile.Fields.Placeholder.Label" = "Etichetta"; "Scene.Profile.Fields.Verified.Long" = "La proprietà di questo collegamento è stata verificata il %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 01701dfc2..3d32c96d1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "本当にサインアウトしますか?"; "Common.Alerts.SignOut.Title" = "サインアウト"; "Common.Alerts.SignUpFailure.Title" = "サインアップに失敗しました"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "投票は終了しました"; "Common.Alerts.VoteFailure.Title" = "投票の失敗"; "Common.Controls.Actions.Add" = "追加"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "新規作成"; "Common.Controls.Actions.Confirm" = "確認"; "Common.Controls.Actions.Continue" = "続ける"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "写真をコピー"; "Common.Controls.Actions.Delete" = "削除"; "Common.Controls.Actions.Discard" = "破棄"; @@ -49,16 +53,18 @@ "Common.Controls.Actions.Reply" = "返信"; "Common.Controls.Actions.ReportUser" = "%@を通報"; "Common.Controls.Actions.Save" = "保存"; -"Common.Controls.Actions.SavePhoto" = "写真を撮る"; +"Common.Controls.Actions.SavePhoto" = "写真を保存"; "Common.Controls.Actions.SeeMore" = "もっと見る"; "Common.Controls.Actions.Settings" = "設定"; "Common.Controls.Actions.Share" = "共有"; "Common.Controls.Actions.SharePost" = "投稿を共有"; "Common.Controls.Actions.ShareUser" = "%@を共有"; -"Common.Controls.Actions.SignIn" = "Log in"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignIn" = "ログイン"; +"Common.Controls.Actions.SignUp" = "アカウント作成"; "Common.Controls.Actions.Skip" = "スキップ"; "Common.Controls.Actions.TakePhoto" = "写真を撮る"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "再実行"; "Common.Controls.Actions.UnblockDomain" = "%@のブロックを解除"; "Common.Controls.Friendship.Block" = "ブロック"; @@ -68,13 +74,13 @@ "Common.Controls.Friendship.EditInfo" = "編集"; "Common.Controls.Friendship.Follow" = "フォロー"; "Common.Controls.Friendship.Following" = "フォロー中"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.HideReblogs" = "ブーストを非表示"; "Common.Controls.Friendship.Mute" = "ミュート"; "Common.Controls.Friendship.MuteUser" = "%@をミュート"; "Common.Controls.Friendship.Muted" = "ミュート済み"; "Common.Controls.Friendship.Pending" = "保留"; "Common.Controls.Friendship.Request" = "リクエスト"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "ブーストを表示"; "Common.Controls.Friendship.Unblock" = "ブロックを解除"; "Common.Controls.Friendship.UnblockUser" = "%@のブロックを解除"; "Common.Controls.Friendship.Unmute" = "ミュートを解除"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "メニュー"; "Common.Controls.Status.Actions.Reblog" = "ブースト"; "Common.Controls.Status.Actions.Reply" = "返信"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "GIFを表示"; "Common.Controls.Status.Actions.ShowImage" = "画像を表示"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; @@ -107,11 +114,13 @@ "Common.Controls.Status.Actions.Unfavorite" = "お気に入り登録を取り消す"; "Common.Controls.Status.Actions.Unreblog" = "ブーストを戻す"; "Common.Controls.Status.ContentWarning" = "コンテンツ警告"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "どこかをタップして表示"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; -"Common.Controls.Status.MetaEntity.Url" = "Link: %@"; +"Common.Controls.Status.MetaEntity.Email" = "メールアドレス: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "ハッシュタグ: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "プロフィールを表示: %@"; +"Common.Controls.Status.MetaEntity.Url" = "リンク: %@"; "Common.Controls.Status.Poll.Closed" = "終了"; "Common.Controls.Status.Poll.Vote" = "投票"; "Common.Controls.Status.SensitiveContent" = "閲覧注意"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "メンション"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "タップして表示"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@がブースト"; "Common.Controls.Status.UserRepliedTo" = "%@に返信"; "Common.Controls.Status.Visibility.Direct" = "この投稿はメンションされたユーザーに限り見ることができます。"; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "この投稿はフォロワーに限り見ることができます。"; "Common.Controls.Status.Visibility.Unlisted" = "この投稿は誰でも見ることができますが、公開タイムラインには表示されません。"; "Common.Controls.Tabs.Home" = "ホーム"; -"Common.Controls.Tabs.Notification" = "通知"; +"Common.Controls.Tabs.Notifications" = "通知"; "Common.Controls.Tabs.Profile" = "プロフィール"; -"Common.Controls.Tabs.Search" = "検索"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "フィルター済み"; "Common.Controls.Timeline.Header.BlockedWarning" = "ブロックされているようです..."; "Common.Controls.Timeline.Header.BlockingWarning" = "ブロックを解除するまでこのユーザーをみることはできません。 @@ -151,32 +164,32 @@ "Scene.AccountList.AddAccount" = "アカウントを追加"; "Scene.AccountList.DismissAccountSwitcher" = "アカウント切替画面を閉じます"; "Scene.AccountList.TabBarHint" = "現在のアカウント: %@. ダブルタップしてアカウント切替画面を表示します"; -"Scene.Bookmark.Title" = "Bookmarks"; -"Scene.Compose.Accessibility.AppendAttachment" = "アタッチメントの追加"; +"Scene.Bookmark.Title" = "ブックマーク"; +"Scene.Compose.Accessibility.AppendAttachment" = "添付ファイルを追加"; "Scene.Compose.Accessibility.AppendPoll" = "投票を追加"; "Scene.Compose.Accessibility.CustomEmojiPicker" = "カスタム絵文字ピッカー"; "Scene.Compose.Accessibility.DisableContentWarning" = "閲覧注意を無効にする"; "Scene.Compose.Accessibility.EnableContentWarning" = "閲覧注意を有効にする"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "投稿オプション"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "投稿の表示メニュー"; "Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; "Scene.Compose.Accessibility.RemovePoll" = "投票を消去"; "Scene.Compose.Attachment.AttachmentBroken" = "%@は壊れていてMastodonにアップロードできません。"; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; +"Scene.Compose.Attachment.AttachmentTooLarge" = "添付ファイルが大きすぎます"; "Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; "Scene.Compose.Attachment.CompressingState" = "Compressing..."; "Scene.Compose.Attachment.DescriptionPhoto" = "閲覧が難しいユーザーへの画像説明"; "Scene.Compose.Attachment.DescriptionVideo" = "閲覧が難しいユーザーへの映像説明"; -"Scene.Compose.Attachment.LoadFailed" = "Load Failed"; +"Scene.Compose.Attachment.LoadFailed" = "読み込みに失敗しました"; "Scene.Compose.Attachment.Photo" = "写真"; "Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; +"Scene.Compose.Attachment.UploadFailed" = "アップロードに失敗しました"; "Scene.Compose.Attachment.Video" = "動画"; "Scene.Compose.AutoComplete.SpaceToAdd" = "スペースを追加"; "Scene.Compose.ComposeAction" = "投稿"; "Scene.Compose.ContentInputPlaceholder" = "気になることを入力またはペースト"; "Scene.Compose.ContentWarning.Placeholder" = "ここに警告を書いてください..."; -"Scene.Compose.Keyboard.AppendAttachmentEntry" = "アタッチメントを追加 - %@"; +"Scene.Compose.Keyboard.AppendAttachmentEntry" = "添付ファイルを追加 - %@"; "Scene.Compose.Keyboard.DiscardPost" = "投稿を破棄"; "Scene.Compose.Keyboard.PublishPost" = "投稿する"; "Scene.Compose.Keyboard.SelectVisibilityEntry" = "公開設定を選択 - %@"; @@ -212,7 +225,7 @@ "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "メールアプリを開く"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "メールを確認"; "Scene.ConfirmEmail.Subtitle" = "先程 %@ にメールを送信しました。リンクをタップしてアカウントを確認してください。"; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "メールで送られたリンクへアクセスし、アカウントを認証してください"; "Scene.ConfirmEmail.Title" = "さいごにもうひとつ。"; "Scene.Discovery.Intro" = "あなたのMastodonサーバーで注目を集めている投稿がここに表示されます。"; "Scene.Discovery.Tabs.Community" = "コミュニティ"; @@ -223,7 +236,13 @@ "Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "お気に入り"; -"Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FavoritedBy.Title" = "お気に入り"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "他のサーバーからのフォロワーは表示されません。"; "Scene.Follower.Title" = "フォロワー"; "Scene.Following.Footer" = "他のサーバーにいるフォローは表示されません。"; @@ -235,8 +254,8 @@ "Scene.HomeTimeline.NavigationBarState.Published" = "投稿しました!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "投稿中..."; "Scene.HomeTimeline.Title" = "ホーム"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; +"Scene.Login.ServerSearchField.Placeholder" = "URLを入力またはサーバーを検索"; +"Scene.Login.Subtitle" = "アカウントを作成したサーバーにログインします。"; "Scene.Login.Title" = "Welcome back"; "Scene.Notification.FollowRequest.Accept" = "承認"; "Scene.Notification.FollowRequest.Accepted" = "承諾済み"; @@ -263,6 +282,7 @@ "Scene.Profile.Dashboard.Following" = "フォロー"; "Scene.Profile.Dashboard.Posts" = "投稿"; "Scene.Profile.Fields.AddRow" = "行追加"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "コンテンツ"; "Scene.Profile.Fields.Placeholder.Label" = "ラベル"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; @@ -270,12 +290,12 @@ "Scene.Profile.Header.FollowsYou" = "フォローされています"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "%@をブロックしますか?"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "アカウントをブロック"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "ブーストを非表示にしますか?"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "ブーストを非表示"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "%@をミュートしますか?"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "アカウントをミュート"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "ブーストを表示しますか?"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "ブーストを表示"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "%@のブロックを解除しますか?"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "アカウントのブロックを解除"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "%@をミュートしますか?"; @@ -285,7 +305,7 @@ "Scene.Profile.SegmentedControl.Posts" = "投稿"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "投稿と返信"; "Scene.Profile.SegmentedControl.Replies" = "返信"; -"Scene.RebloggedBy.Title" = "Reblogged By"; +"Scene.RebloggedBy.Title" = "ブースト"; "Scene.Register.Error.Item.Agreement" = "契約"; "Scene.Register.Error.Item.Email" = "メール"; "Scene.Register.Error.Item.Locale" = "地域"; @@ -329,15 +349,15 @@ "Scene.Report.Step1" = "ステップ 1/2"; "Scene.Report.Step2" = "ステップ 2/2"; "Scene.Report.StepFinal.BlockUser" = "%@をブロック"; -"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "見えないようにしたいですか?"; "Scene.Report.StepFinal.MuteUser" = "%@をミュート"; -"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "相手はあなたの投稿を見たり、フォローしたりできなくなります。あなたにブロックされていることはわかります。"; "Scene.Report.StepFinal.Unfollow" = "フォロー解除"; "Scene.Report.StepFinal.UnfollowUser" = "%@をフォロー解除"; "Scene.Report.StepFinal.Unfollowed" = "フォロー解除しました"; -"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Mastodonで気に入らないものを見た場合、その人をあなたの体験から取り除くことができます。"; "Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "私たちが確認している間でも、あなたは%@さんに対して対応することができます。"; -"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "ホームに投稿やブーストは表示されなくなります。相手にミュートしたことは伝わりません。"; "Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "その他に私たちに伝えておくべき事はありますか?"; "Scene.Report.StepFour.Step4Of4" = "ステップ 4/4"; "Scene.Report.StepOne.IDontLikeIt" = "興味がありません"; @@ -353,11 +373,11 @@ "Scene.Report.StepOne.WhatsWrongWithThisPost" = "この投稿のどこが問題ですか?"; "Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@さんのどこが問題ですか?"; "Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "ルールに違反しているのを見つけた場合"; -"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; -"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "この通報を裏付けるような投稿はありますか?"; +"Scene.Report.StepThree.SelectAllThatApply" = "当てはまるものをすべて選んでください"; "Scene.Report.StepThree.Step3Of4" = "ステップ 3/4"; -"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; -"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "興味がありません"; +"Scene.Report.StepTwo.SelectAllThatApply" = "当てはまるものをすべて選んでください"; "Scene.Report.StepTwo.Step2Of4" = "ステップ 2/4"; "Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "どのルールに違反していますか?"; "Scene.Report.TextPlaceholder" = "追加コメントを入力"; @@ -399,11 +419,11 @@ "Scene.ServerPicker.EmptyState.BadNetwork" = "データの読み込み中に何か問題が発生しました。インターネットの接続状況を確認してください。"; "Scene.ServerPicker.EmptyState.FindingServers" = "利用可能なサーバーの検索..."; "Scene.ServerPicker.EmptyState.NoResults" = "なし"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "コミュニティを検索またはURLを入力"; "Scene.ServerPicker.Label.Category" = "カテゴリー"; "Scene.ServerPicker.Label.Language" = "言語"; "Scene.ServerPicker.Label.Users" = "ユーザー"; -"Scene.ServerPicker.Subtitle" = "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers."; +"Scene.ServerPicker.Subtitle" = "お住まいの地域、興味、目的に基づいてサーバーを選択してください。 サーバーに関係なく、Mastodonの誰とでも話せます。"; "Scene.ServerPicker.Title" = "サーバーを選択"; "Scene.ServerRules.Button.Confirm" = "同意する"; "Scene.ServerRules.PrivacyPolicy" = "プライバシーポリシー"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index 781143b71..43a1d385a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -22,6 +22,9 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Alerts.SignOut.Message" = "Tebɣiḍ ad teffɣeḍ?"; "Common.Alerts.SignOut.Title" = "Ffeɣ"; "Common.Alerts.SignUpFailure.Title" = "Tuccḍa deg unekcum"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Tafrant tfuk"; "Common.Alerts.VoteFailure.Title" = "Tuccḍa deg ufran"; "Common.Controls.Actions.Add" = "Rnu"; @@ -31,6 +34,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.Compose" = "Sudes"; "Common.Controls.Actions.Confirm" = "Sentem"; "Common.Controls.Actions.Continue" = "Kemmel"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Nɣel tawlaft"; "Common.Controls.Actions.Delete" = "Kkes"; "Common.Controls.Actions.Discard" = "Sefsex"; @@ -59,6 +63,8 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.SignUp" = "Snulfu-d amiḍan"; "Common.Controls.Actions.Skip" = "Zgel"; "Common.Controls.Actions.TakePhoto" = "Ṭṭef tawlaft"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Ɛreḍ tikkelt-nniḍen"; "Common.Controls.Actions.UnblockDomain" = "Serreḥ i %@"; "Common.Controls.Friendship.Block" = "Sewḥel"; @@ -100,6 +106,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Status.Actions.Menu" = "Umuɣ"; "Common.Controls.Status.Actions.Reblog" = "Aɛiwed n usuffeɣ"; "Common.Controls.Status.Actions.Reply" = "Err"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Sken GIF"; "Common.Controls.Status.Actions.ShowImage" = "Sken tugna"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Sken ameɣri n tvidyut"; @@ -107,6 +114,8 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Status.Actions.Unfavorite" = "Kkes seg yismenyifen"; "Common.Controls.Status.Actions.Unreblog" = "Sefsex allus n usuffeɣ"; "Common.Controls.Status.ContentWarning" = "Alɣu n ugbur"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Sit anida tebɣiḍ i wakken ad twaliḍ"; "Common.Controls.Status.MetaEntity.Email" = "Tansa imayl : %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Ahacṭag : %@"; @@ -124,6 +133,10 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Status.Tag.Mention" = "Tabdart"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Sit i uskan"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "Tettwasuffeɣ-d %@ i tikkelt-nniḍen"; "Common.Controls.Status.UserRepliedTo" = "Yerra ɣef %@"; "Common.Controls.Status.Visibility.Direct" = "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a."; @@ -131,9 +144,9 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Status.Visibility.PrivateFromMe" = "D ineḍfaren-is kan i izemren ad walin tsuffeɣ-a."; "Common.Controls.Status.Visibility.Unlisted" = "Yal wa yezmer ad iwali tsuffeɣt-a maca ur d-tettwaskaneḍ ara deg yizirig n wakud azayaz."; "Common.Controls.Tabs.Home" = "Agejdan"; -"Common.Controls.Tabs.Notification" = "Tilɣa"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Amaɣnu"; -"Common.Controls.Tabs.Search" = "Nadi"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Yettwasizdeg"; "Common.Controls.Timeline.Header.BlockedWarning" = "Ur tezmireḍ ara ad twaliḍ amaɣnu n useqdac-a Akka i as-d-yettban umaɣnu-inek."; @@ -229,6 +242,12 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Familiarfollowers.Title" = "Ineḍfaren i tessneḍ"; "Scene.Favorite.Title" = "Ismenyifen-ik·im"; "Scene.FavoritedBy.Title" = "Ismenyaf-it"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."; "Scene.Follower.Title" = "aneḍfar"; "Scene.Following.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."; @@ -268,6 +287,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Profile.Dashboard.Following" = "iṭafaṛ"; "Scene.Profile.Dashboard.Posts" = "tisuffaɣ"; "Scene.Profile.Fields.AddRow" = "Rnu izirig"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Agbur"; "Scene.Profile.Fields.Placeholder.Label" = "Tabzimt"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 03ac1f46d..6eaa474f0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -22,6 +22,9 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Alerts.SignOut.Message" = "Ma tu dixwazî ku derkevî?"; "Common.Alerts.SignOut.Title" = "Derkeve"; "Common.Alerts.SignUpFailure.Title" = "Tomarkirin têkçû"; +"Common.Alerts.TranslationFailed.Button" = "BAŞ E"; +"Common.Alerts.TranslationFailed.Message" = "Werger têk çû. Dibe ku rêvebir werger li ser vê rajakarê çalak nekiribe an jî ev rajakar guhertoyek kevntir a Mastodon e ku werger hîn nehatiye piştgirîkirin."; +"Common.Alerts.TranslationFailed.Title" = "Nîşe"; "Common.Alerts.VoteFailure.PollEnded" = "Rapirsîya qediya"; "Common.Alerts.VoteFailure.Title" = "Dengdayîn têkçû"; "Common.Controls.Actions.Add" = "Tevlî bike"; @@ -31,6 +34,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.Compose" = "Binivîsîne"; "Common.Controls.Actions.Confirm" = "Bipejirîne"; "Common.Controls.Actions.Continue" = "Bidomîne"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Wêneyê jê bigire"; "Common.Controls.Actions.Delete" = "Jê bibe"; "Common.Controls.Actions.Discard" = "Biavêje"; @@ -59,6 +63,8 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.SignUp" = "Ajimêr biafirîne"; "Common.Controls.Actions.Skip" = "Derbas bike"; "Common.Controls.Actions.TakePhoto" = "Wêne bikişîne"; +"Common.Controls.Actions.TranslatePost.Title" = "Ji %@ hate wergerandin"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Nenas"; "Common.Controls.Actions.TryAgain" = "Dîsa biceribîne"; "Common.Controls.Actions.UnblockDomain" = "%@ asteng neke"; "Common.Controls.Friendship.Block" = "Asteng bike"; @@ -100,6 +106,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Status.Actions.Menu" = "Kulîn"; "Common.Controls.Status.Actions.Reblog" = "Ji nû ve nivîsandin"; "Common.Controls.Status.Actions.Reply" = "Bersivê bide"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "GIF nîşan bide"; "Common.Controls.Status.Actions.ShowImage" = "Wêneyê nîşan bide"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Lêdera vîdyoyê nîşan bide"; @@ -107,6 +114,8 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Status.Actions.Unfavorite" = "Nebijarte"; "Common.Controls.Status.Actions.Unreblog" = "Ji nû ve nivîsandinê vegere"; "Common.Controls.Status.ContentWarning" = "Hişyariya naverokê"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Ji bo eşkerekirinê li derekî bitikîne"; "Common.Controls.Status.MetaEntity.Email" = "Navnîşanên e-nameyê: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtagê: %@"; @@ -124,6 +133,10 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Status.Tag.Mention" = "Qalkirin"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Ji bo dîtinê bitikîne"; +"Common.Controls.Status.Translation.ShowOriginal" = "A resen nîşan bide"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Nenas"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ ji nû ve nivîsand"; "Common.Controls.Status.UserRepliedTo" = "Bersiv da %@"; "Common.Controls.Status.Visibility.Direct" = "Tenê bikarhênerê qalkirî dikare vê şandiyê bibîne."; @@ -131,9 +144,9 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Tenê şopînerên min dikarin vê şandiyê bibînin."; "Common.Controls.Status.Visibility.Unlisted" = "Her kes dikare vê şandiyê bibîne lê nayê nîşandan di demnameya gelemperî de."; "Common.Controls.Tabs.Home" = "Serrûpel"; -"Common.Controls.Tabs.Notification" = "Agahdarî"; +"Common.Controls.Tabs.Notifications" = "Agahdarî"; "Common.Controls.Tabs.Profile" = "Profîl"; -"Common.Controls.Tabs.Search" = "Bigere"; +"Common.Controls.Tabs.SearchAndExplore" = "Bigere û vekole"; "Common.Controls.Timeline.Filtered" = "Parzûnkirî"; "Common.Controls.Timeline.Header.BlockedWarning" = "Tu nikarî profîla vî/ê bikarhênerî bibînî heya ku ew astengiyê li ser te rakin."; @@ -230,6 +243,12 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Familiarfollowers.Title" = "Şopînerên ku tu wan nas dikî"; "Scene.Favorite.Title" = "Bijarteyên te"; "Scene.FavoritedBy.Title" = "Hatiye hezkirin ji aliyê"; +"Scene.FollowedTags.Actions.Follow" = "Bişopîne"; +"Scene.FollowedTags.Actions.Unfollow" = "Neşopîne"; +"Scene.FollowedTags.Header.Participants" = "beşdar"; +"Scene.FollowedTags.Header.Posts" = "şandî"; +"Scene.FollowedTags.Header.PostsToday" = "şandiyên îro"; +"Scene.FollowedTags.Title" = "Hashtagên şopandî"; "Scene.Follower.Footer" = "Şopîner ji rajekerên din nayê dîtin."; "Scene.Follower.Title" = "şopîner"; "Scene.Following.Footer" = "Şopandin ji rajekerên din nayê dîtin."; @@ -269,6 +288,7 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Profile.Dashboard.Following" = "dişopîne"; "Scene.Profile.Dashboard.Posts" = "şandî"; "Scene.Profile.Fields.AddRow" = "Rêzê tevlî bike"; +"Scene.Profile.Fields.Joined" = "Dîroka tevlîbûnê"; "Scene.Profile.Fields.Placeholder.Content" = "Naverok"; "Scene.Profile.Fields.Placeholder.Label" = "Nîşan"; "Scene.Profile.Fields.Verified.Long" = "Xwedaniya li vê girêdanê di %@ de hatiye kontrolkirin"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 0d8f1dd0f..6e7839852 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -21,6 +21,9 @@ "Common.Alerts.SignOut.Message" = "Weet je zeker dat je wilt uitloggen?"; "Common.Alerts.SignOut.Title" = "Log-uit"; "Common.Alerts.SignUpFailure.Title" = "Registratiefout"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "De peiling is beëindigd"; "Common.Alerts.VoteFailure.Title" = "Stemmen Mislukt"; "Common.Controls.Actions.Add" = "Voeg toe"; @@ -30,6 +33,7 @@ "Common.Controls.Actions.Compose" = "Schrijf bericht"; "Common.Controls.Actions.Confirm" = "Bevestigen"; "Common.Controls.Actions.Continue" = "Ga verder"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Kopieer foto"; "Common.Controls.Actions.Delete" = "Verwijder"; "Common.Controls.Actions.Discard" = "Weggooien"; @@ -54,10 +58,12 @@ "Common.Controls.Actions.Share" = "Deel"; "Common.Controls.Actions.SharePost" = "Deel bericht"; "Common.Controls.Actions.ShareUser" = "Delen %@"; -"Common.Controls.Actions.SignIn" = "Log in"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignIn" = "Inloggen"; +"Common.Controls.Actions.SignUp" = "Account aanmaken"; "Common.Controls.Actions.Skip" = "Overslaan"; "Common.Controls.Actions.TakePhoto" = "Maak foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Probeer Opnieuw"; "Common.Controls.Actions.UnblockDomain" = "Deblokkeer %@"; "Common.Controls.Friendship.Block" = "Blokkeren"; @@ -67,13 +73,13 @@ "Common.Controls.Friendship.EditInfo" = "Bewerken"; "Common.Controls.Friendship.Follow" = "Volgen"; "Common.Controls.Friendship.Following" = "Gevolgd"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.HideReblogs" = "Verberg reblogs"; "Common.Controls.Friendship.Mute" = "Negeren"; "Common.Controls.Friendship.MuteUser" = "Negeer %@"; "Common.Controls.Friendship.Muted" = "Genegeerd"; "Common.Controls.Friendship.Pending" = "In afwachting"; "Common.Controls.Friendship.Request" = "Verzoeken"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "Toon reblogs"; "Common.Controls.Friendship.Unblock" = "Deblokkeer"; "Common.Controls.Friendship.UnblockUser" = "Deblokkeer %@"; "Common.Controls.Friendship.Unmute" = "Niet langer negeren"; @@ -99,6 +105,7 @@ "Common.Controls.Status.Actions.Menu" = "Menu"; "Common.Controls.Status.Actions.Reblog" = "Delen"; "Common.Controls.Status.Actions.Reply" = "Reageren"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "GIF weergeven"; "Common.Controls.Status.Actions.ShowImage" = "Toon afbeelding"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Toon videospeler"; @@ -106,10 +113,12 @@ "Common.Controls.Status.Actions.Unfavorite" = "Verwijderen uit Favorieten"; "Common.Controls.Status.Actions.Unreblog" = "Delen ongedaan maken"; "Common.Controls.Status.ContentWarning" = "Inhoudswaarschuwing"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Tap hier om te tonen"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; +"Common.Controls.Status.MetaEntity.Email" = "E-mailadres: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Profiel weergeven: %@"; "Common.Controls.Status.MetaEntity.Url" = "Link: %@"; "Common.Controls.Status.Poll.Closed" = "Gesloten"; "Common.Controls.Status.Poll.Vote" = "Stemmen"; @@ -123,6 +132,10 @@ "Common.Controls.Status.Tag.Mention" = "Vermelden"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tik om te onthullen"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ heeft gedeeld"; "Common.Controls.Status.UserRepliedTo" = "Reactie op %@"; "Common.Controls.Status.Visibility.Direct" = "Alleen de vermelde persoon kan dit bericht zien."; @@ -130,9 +143,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "Alleen mijn volgers kunnen dit bericht zien."; "Common.Controls.Status.Visibility.Unlisted" = "Iedereen kan dit bericht zien maar het wordt niet in de publieke tijdlijn getoond."; "Common.Controls.Tabs.Home" = "Start"; -"Common.Controls.Tabs.Notification" = "Melding"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Profiel"; -"Common.Controls.Tabs.Search" = "Zoek"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Gefilterd"; "Common.Controls.Timeline.Header.BlockedWarning" = "U kunt het profiel van deze gebruiker niet bekijken zolang u geblokkeerd bent."; "Common.Controls.Timeline.Header.BlockingWarning" = "U kunt het profiel van deze geblokkeerde gebruiker niet bekijken. @@ -156,20 +169,20 @@ Uw profiel ziet er zo uit voor hen."; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Eigen Emojikiezer"; "Scene.Compose.Accessibility.DisableContentWarning" = "Inhoudswaarschuwing Uitschakelen"; "Scene.Compose.Accessibility.EnableContentWarning" = "Inhoudswaarschuwing inschakelen"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "Plaats Bericht Opties"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Berichtzichtbaarheidsmenu"; -"Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; +"Scene.Compose.Accessibility.PostingAs" = "Plaats bericht als %@"; "Scene.Compose.Accessibility.RemovePoll" = "Peiling verwijderen"; "Scene.Compose.Attachment.AttachmentBroken" = "Deze %@ is corrupt en kan niet geüpload worden naar Mastodon."; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; -"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; -"Scene.Compose.Attachment.CompressingState" = "Compressing..."; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Bijlage te groot"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Kan de media in de bijlage niet herkennen"; +"Scene.Compose.Attachment.CompressingState" = "Bezig met comprimeren..."; "Scene.Compose.Attachment.DescriptionPhoto" = "Omschrijf de foto voor mensen met een visuele beperking..."; "Scene.Compose.Attachment.DescriptionVideo" = "Omschrijf de video voor mensen met een visuele beperking..."; -"Scene.Compose.Attachment.LoadFailed" = "Load Failed"; +"Scene.Compose.Attachment.LoadFailed" = "Laden mislukt"; "Scene.Compose.Attachment.Photo" = "foto"; -"Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; +"Scene.Compose.Attachment.ServerProcessingState" = "Server is bezig met verwerken..."; +"Scene.Compose.Attachment.UploadFailed" = "Uploaden mislukt"; "Scene.Compose.Attachment.Video" = "video"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Spaties toe te voegen"; "Scene.Compose.ComposeAction" = "Publiceren"; @@ -190,8 +203,8 @@ Uw profiel ziet er zo uit voor hen."; "Scene.Compose.Poll.OptionNumber" = "Optie %ld"; "Scene.Compose.Poll.SevenDays" = "7 Dagen"; "Scene.Compose.Poll.SixHours" = "6 Uur"; -"Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; -"Scene.Compose.Poll.ThePollIsInvalid" = "The poll is invalid"; +"Scene.Compose.Poll.ThePollHasEmptyOption" = "De peiling heeft een lege optie"; +"Scene.Compose.Poll.ThePollIsInvalid" = "De peiling is ongeldig"; "Scene.Compose.Poll.ThirtyMinutes" = "30 minuten"; "Scene.Compose.Poll.ThreeDays" = "3 Dagen"; "Scene.Compose.ReplyingToUser" = "reageren op %@"; @@ -212,36 +225,42 @@ Uw profiel ziet er zo uit voor hen."; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Ga naar uw inbox."; "Scene.ConfirmEmail.Subtitle" = "We hebben een e-mail gestuurd naar %@, klik op de link om uw account te bevestigen."; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tik op de link in de e-mail die je hebt ontvangen om uw account te verifiëren"; "Scene.ConfirmEmail.Title" = "Nog één ding."; "Scene.Discovery.Intro" = "Dit zijn de berichten die populair zijn in jouw Mastodon-kringen."; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Tabs.Community" = "Gemeenschap"; "Scene.Discovery.Tabs.ForYou" = "Voor jou"; "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "Nieuws"; "Scene.Discovery.Tabs.Posts" = "Berichten"; -"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; -"Scene.Familiarfollowers.Title" = "Followers you familiar"; +"Scene.Familiarfollowers.FollowedByNames" = "Gevolgd door %@"; +"Scene.Familiarfollowers.Title" = "Volgers die je kent"; "Scene.Favorite.Title" = "Uw favorieten"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Volgers van andere servers worden niet weergegeven."; -"Scene.Follower.Title" = "follower"; +"Scene.Follower.Title" = "volger"; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; -"Scene.Following.Title" = "following"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; +"Scene.Following.Title" = "volgend"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tik om naar boven te scrollen en tik nogmaals om terug te keren naar de vorige locatie"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo knop"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "Bericht publiceren..."; "Scene.HomeTimeline.Title" = "Start"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; -"Scene.Notification.FollowRequest.Accept" = "Accept"; -"Scene.Notification.FollowRequest.Accepted" = "Accepted"; -"Scene.Notification.FollowRequest.Reject" = "reject"; -"Scene.Notification.FollowRequest.Rejected" = "Rejected"; +"Scene.Login.ServerSearchField.Placeholder" = "Voer URL in of zoek naar uw server"; +"Scene.Login.Subtitle" = "Log je in op de server waarop je je account hebt aangemaakt."; +"Scene.Login.Title" = "Welkom terug"; +"Scene.Notification.FollowRequest.Accept" = "Accepteren"; +"Scene.Notification.FollowRequest.Accepted" = "Geaccepteerd"; +"Scene.Notification.FollowRequest.Reject" = "afwijzen"; +"Scene.Notification.FollowRequest.Rejected" = "Afgewezen"; "Scene.Notification.Keyobard.ShowEverything" = "Alles weergeven"; "Scene.Notification.Keyobard.ShowMentions" = "Vermeldingen weergeven"; "Scene.Notification.NotificationDescription.FavoritedYourPost" = "heeft je bericht als favoriet gemrkeerd"; @@ -263,19 +282,20 @@ klik op de link om uw account te bevestigen."; "Scene.Profile.Dashboard.Following" = "volgend"; "Scene.Profile.Dashboard.Posts" = "berichten"; "Scene.Profile.Fields.AddRow" = "Rij Toevoegen"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Inhoud"; "Scene.Profile.Fields.Placeholder.Label" = "Etiket"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; -"Scene.Profile.Fields.Verified.Short" = "Verified on %@"; -"Scene.Profile.Header.FollowsYou" = "Follows You"; +"Scene.Profile.Fields.Verified.Long" = "Eigendom van deze link is gecontroleerd op %@"; +"Scene.Profile.Fields.Verified.Short" = "Geverifieerd op %@"; +"Scene.Profile.Header.FollowsYou" = "Volgt jou"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bevestig om %@ te blokkeren"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blokkeer account"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Bevestig om reblogs te verbergen"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Verberg reblogs"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bevestig om %@ te negeren"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Negeer account"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Bevestig om reblogs te tonen"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Toon reblogs"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Bevestig om %@ te deblokkeren"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Deblokkeer Account"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Bevestig om %@ te negeren"; @@ -318,7 +338,7 @@ klik op de link om uw account te bevestigen."; "Scene.Register.Input.Password.Require" = "Je wachtwoord moet ten minste:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Deze gebruikersnaam is al in gebruik."; "Scene.Register.Input.Username.Placeholder" = "gebruikersnaam"; -"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Laten we je account instellen op %@"; "Scene.Register.Title" = "Vertel ons over uzelf."; "Scene.Report.Content1" = "Zijn er nog meer berichten die u aan het rapport wilt toevoegen?"; "Scene.Report.Content2" = "Is er iets anders over dit rapport dat de moderators zouden moeten weten?"; @@ -346,12 +366,12 @@ klik op de link om uw account te bevestigen."; "Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; "Scene.Report.StepOne.ItsSpam" = "It’s spam"; "Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; -"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; -"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Selecteer de beste overeenkomst"; +"Scene.Report.StepOne.Step1Of4" = "Stap 1 van 4"; "Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; -"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; -"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; -"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Wat is er mis met dit bericht?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Wat is er mis met dit bericht?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Wat is er mis met %@?"; "Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; "Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; "Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; @@ -399,11 +419,11 @@ klik op de link om uw account te bevestigen."; "Scene.ServerPicker.EmptyState.BadNetwork" = "Er is een fout opgetreden bij het laden van de gegevens. Controleer uw internetverbinding."; "Scene.ServerPicker.EmptyState.FindingServers" = "Beschikbare servers zoeken..."; "Scene.ServerPicker.EmptyState.NoResults" = "Geen resultaten"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Zoek naar gemeenschappen of voer URL in"; "Scene.ServerPicker.Label.Category" = "CATEGORIE"; "Scene.ServerPicker.Label.Language" = "TAAL"; "Scene.ServerPicker.Label.Users" = "GEBRUIKERS"; -"Scene.ServerPicker.Subtitle" = "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers."; +"Scene.ServerPicker.Subtitle" = "Kies een server gebaseerd op je regio, interesses, of een algemene server. Je kunt nog steeds chatten met iedereen op Mastodon, ongeacht op welke server je zit."; "Scene.ServerPicker.Title" = "Kies een server, welke dan ook."; "Scene.ServerRules.Button.Confirm" = "Ik Ga Akkoord"; "Scene.ServerRules.PrivacyPolicy" = "privacybeleid"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict index 84769b0c1..29d0ec841 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 unread notification other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 2ad16cb77..8275902d4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "Вы действительно хотите выйти из учётной записи?"; "Common.Alerts.SignOut.Title" = "Выход"; "Common.Alerts.SignUpFailure.Title" = "Ошибка регистрации"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Опрос уже завершился"; "Common.Alerts.VoteFailure.Title" = "Не удалось проголосовать"; "Common.Controls.Actions.Add" = "Добавить"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "Написать"; "Common.Controls.Actions.Confirm" = "Подтвердить"; "Common.Controls.Actions.Continue" = "Продолжить"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Скопировать изображение"; "Common.Controls.Actions.Delete" = "Удалить"; "Common.Controls.Actions.Discard" = "Отмена"; @@ -59,6 +63,8 @@ "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Пропустить"; "Common.Controls.Actions.TakePhoto" = "Сделать фото"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Попробовать снова"; "Common.Controls.Actions.UnblockDomain" = "Разблокировать %@"; "Common.Controls.Friendship.Block" = "Заблокировать"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "Меню"; "Common.Controls.Status.Actions.Reblog" = "Продвинуть"; "Common.Controls.Status.Actions.Reply" = "Ответить"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "Показать GIF"; "Common.Controls.Status.Actions.ShowImage" = "Показать изображение"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Показать видеопроигрыватель"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "Убрать из избранного"; "Common.Controls.Status.Actions.Unreblog" = "Убрать продвижение"; "Common.Controls.Status.ContentWarning" = "Предупреждение о содержании"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Нажмите в любом месте, чтобы показать"; "Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "Упоминание"; "Common.Controls.Status.Tag.Url" = "Ссылка"; "Common.Controls.Status.TapToReveal" = "Нажмите, чтобы показать"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ продвинул(а)"; "Common.Controls.Status.UserRepliedTo" = "Ответил(а) %@"; "Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; "Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Главная"; -"Common.Controls.Tabs.Notification" = "Уведомление"; +"Common.Controls.Tabs.Notifications" = "Notifications"; "Common.Controls.Tabs.Profile" = "Профиль"; -"Common.Controls.Tabs.Search" = "Поиск"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "Отфильтровано"; "Common.Controls.Timeline.Header.BlockedWarning" = "Вы не можете просматривать профиль этого пользователя @@ -240,6 +253,12 @@ "Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Ваше избранное"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; "Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; @@ -279,6 +298,7 @@ "Scene.Profile.Dashboard.Following" = "подписки"; "Scene.Profile.Dashboard.Posts" = "посты"; "Scene.Profile.Fields.AddRow" = "Добавить строку"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Содержимое"; "Scene.Profile.Fields.Placeholder.Label" = "Ярлык"; "Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict index c9552a9e4..d43386ad9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict @@ -15,11 +15,11 @@ one 1 unread notification few - %ld unread notification + %ld unread notifications many - %ld unread notification + %ld unread notifications other - %ld unread notification + %ld unread notifications a11y.plural.count.input_limit_exceeds diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings index 44f868442..1aa2aab73 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings @@ -22,6 +22,9 @@ Preverite svojo internetno povezavo."; "Common.Alerts.SignOut.Message" = "Ali ste prepričani, da se želite odjaviti?"; "Common.Alerts.SignOut.Title" = "Odjava"; "Common.Alerts.SignUpFailure.Title" = "Neuspela registracija"; +"Common.Alerts.TranslationFailed.Button" = "V redu"; +"Common.Alerts.TranslationFailed.Message" = "Prevod je spodletel. Morda skrbnik ni omogočil prevajanja na tem strežniku ali pa strežnik teče na starejši različici Masotodona, na kateri prevajanje še ni podprto."; +"Common.Alerts.TranslationFailed.Title" = "Opomba"; "Common.Alerts.VoteFailure.PollEnded" = "Anketa je zaključena"; "Common.Alerts.VoteFailure.Title" = "Napaka glasovanja"; "Common.Controls.Actions.Add" = "Dodaj"; @@ -31,6 +34,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.Compose" = "Sestavi"; "Common.Controls.Actions.Confirm" = "Potrdi"; "Common.Controls.Actions.Continue" = "Nadaljuj"; +"Common.Controls.Actions.Copy" = "Kopiraj"; "Common.Controls.Actions.CopyPhoto" = "Kopiraj fotografijo"; "Common.Controls.Actions.Delete" = "Izbriši"; "Common.Controls.Actions.Discard" = "Opusti"; @@ -59,6 +63,8 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.SignUp" = "Ustvari račun"; "Common.Controls.Actions.Skip" = "Preskoči"; "Common.Controls.Actions.TakePhoto" = "Posnemi fotografijo"; +"Common.Controls.Actions.TranslatePost.Title" = "Prevedi iz: %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Neznano"; "Common.Controls.Actions.TryAgain" = "Poskusi ponovno"; "Common.Controls.Actions.UnblockDomain" = "Odblokiraj %@"; "Common.Controls.Friendship.Block" = "Blokiraj"; @@ -100,6 +106,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Status.Actions.Menu" = "Meni"; "Common.Controls.Status.Actions.Reblog" = "Poobjavi"; "Common.Controls.Status.Actions.Reply" = "Odgovori"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Deli povezavo v objavi"; "Common.Controls.Status.Actions.ShowGif" = "Pokaži GIF"; "Common.Controls.Status.Actions.ShowImage" = "Pokaži sliko"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Pokaži predvajalnik"; @@ -107,6 +114,8 @@ Preverite svojo internetno povezavo."; "Common.Controls.Status.Actions.Unfavorite" = "Odstrani iz priljubljenih"; "Common.Controls.Status.Actions.Unreblog" = "Razveljavi poobjavo"; "Common.Controls.Status.ContentWarning" = "Opozorilo o vsebini"; +"Common.Controls.Status.LinkViaUser" = "%@ prek %@"; +"Common.Controls.Status.LoadEmbed" = "Naloži vdelano"; "Common.Controls.Status.MediaContentWarning" = "Tapnite kamorkoli, da razkrijete"; "Common.Controls.Status.MetaEntity.Email" = "E-naslov: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Ključnik: %@"; @@ -124,6 +133,10 @@ Preverite svojo internetno povezavo."; "Common.Controls.Status.Tag.Mention" = "Omeni"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tapnite za razkritje"; +"Common.Controls.Status.Translation.ShowOriginal" = "Pokaži izvirnik"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Neznano"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ je poobjavil_a"; "Common.Controls.Status.UserRepliedTo" = "Odgovarja %@"; "Common.Controls.Status.Visibility.Direct" = "Samo omenjeni uporabnik lahko vidi to objavo."; @@ -131,9 +144,9 @@ Preverite svojo internetno povezavo."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Samo moji sledilci lahko vidijo to objavo."; "Common.Controls.Status.Visibility.Unlisted" = "Vsak lahko vidi to objavo, ni pa prikazana na javni časovnici."; "Common.Controls.Tabs.Home" = "Domov"; -"Common.Controls.Tabs.Notification" = "Obvestilo"; +"Common.Controls.Tabs.Notifications" = "Obvestila"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Iskanje"; +"Common.Controls.Tabs.SearchAndExplore" = "Poišči in razišči"; "Common.Controls.Timeline.Filtered" = "Filtrirano"; "Common.Controls.Timeline.Header.BlockedWarning" = "Profila tega uporabnika ne morete videti, dokler vas ne odblokirajo."; @@ -229,6 +242,12 @@ možno naložiti v Mastodon."; "Scene.Familiarfollowers.Title" = "Znani sledilci"; "Scene.Favorite.Title" = "Vaši priljubljeni"; "Scene.FavoritedBy.Title" = "Med priljubljene dal_a"; +"Scene.FollowedTags.Actions.Follow" = "Sledi"; +"Scene.FollowedTags.Actions.Unfollow" = "Prenehaj slediti"; +"Scene.FollowedTags.Header.Participants" = "udeležencev"; +"Scene.FollowedTags.Header.Posts" = "objav"; +"Scene.FollowedTags.Header.PostsToday" = "objav danes"; +"Scene.FollowedTags.Title" = "Sledene značke"; "Scene.Follower.Footer" = "Sledilci z drugih strežnikov niso prikazani."; "Scene.Follower.Title" = "sledilec"; "Scene.Following.Footer" = "Sledenje z drugih strežnikov ni prikazano."; @@ -268,6 +287,7 @@ možno naložiti v Mastodon."; "Scene.Profile.Dashboard.Following" = "sledi"; "Scene.Profile.Dashboard.Posts" = "Objave"; "Scene.Profile.Fields.AddRow" = "Dodaj vrstico"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "Vsebina"; "Scene.Profile.Fields.Placeholder.Label" = "Oznaka"; "Scene.Profile.Fields.Verified.Long" = "Lastništvo te povezave je bilo preverjeno %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings index 79781cae7..4da00cad1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -22,6 +22,9 @@ Kontrollera din internetanslutning."; "Common.Alerts.SignOut.Message" = "Är du säker på att du vill logga ut?"; "Common.Alerts.SignOut.Title" = "Logga ut"; "Common.Alerts.SignUpFailure.Title" = "Registrering misslyckades"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Översättningen misslyckades. Det kan hända att administratören inte har aktiverat översättningar på den här servern eller att servern kör en äldre version av Mastodon som inte har stöd för översättningar ännu."; +"Common.Alerts.TranslationFailed.Title" = "Anteckning"; "Common.Alerts.VoteFailure.PollEnded" = "Omröstningen har avslutats"; "Common.Alerts.VoteFailure.Title" = "Röstning misslyckades"; "Common.Controls.Actions.Add" = "Lägg till"; @@ -31,6 +34,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Compose" = "Skriv"; "Common.Controls.Actions.Confirm" = "Bekräfta"; "Common.Controls.Actions.Continue" = "Fortsätt"; +"Common.Controls.Actions.Copy" = "Kopiera"; "Common.Controls.Actions.CopyPhoto" = "Kopiera foto"; "Common.Controls.Actions.Delete" = "Radera"; "Common.Controls.Actions.Discard" = "Släng"; @@ -59,6 +63,8 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.SignUp" = "Skapa konto"; "Common.Controls.Actions.Skip" = "Hoppa över"; "Common.Controls.Actions.TakePhoto" = "Ta foto"; +"Common.Controls.Actions.TranslatePost.Title" = "Översätt från %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Okänt"; "Common.Controls.Actions.TryAgain" = "Försök igen"; "Common.Controls.Actions.UnblockDomain" = "Avblockera %@"; "Common.Controls.Friendship.Block" = "Blockera"; @@ -100,6 +106,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Actions.Menu" = "Meny"; "Common.Controls.Status.Actions.Reblog" = "Boosta"; "Common.Controls.Status.Actions.Reply" = "Svara"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Dela länk i inlägg"; "Common.Controls.Status.Actions.ShowGif" = "Visa GIF"; "Common.Controls.Status.Actions.ShowImage" = "Visa bild"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Visa videospelare"; @@ -107,6 +114,8 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Actions.Unfavorite" = "Ta bort favorit"; "Common.Controls.Status.Actions.Unreblog" = "Ångra boost"; "Common.Controls.Status.ContentWarning" = "Innehållsvarning"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Ladda inbäddning"; "Common.Controls.Status.MediaContentWarning" = "Tryck var som helst för att visa"; "Common.Controls.Status.MetaEntity.Email" = "E-postadress: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Tag.Mention" = "Omnämn"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tryck för att visa"; +"Common.Controls.Status.Translation.ShowOriginal" = "Visa original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Okänt"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ boostade"; "Common.Controls.Status.UserRepliedTo" = "Svarade på %@"; "Common.Controls.Status.Visibility.Direct" = "Endast omnämnda användare kan se detta inlägg."; @@ -131,9 +144,9 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Bara mina följare kan se det här inlägget."; "Common.Controls.Status.Visibility.Unlisted" = "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen."; "Common.Controls.Tabs.Home" = "Hem"; -"Common.Controls.Tabs.Notification" = "Notis"; +"Common.Controls.Tabs.Notifications" = "Notiser"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Sök"; +"Common.Controls.Tabs.SearchAndExplore" = "Sök och utforska"; "Common.Controls.Timeline.Filtered" = "Filtrerat"; "Common.Controls.Timeline.Header.BlockedWarning" = "Du kan inte visa den här användarens profil förrän de avblockerar dig."; @@ -229,6 +242,12 @@ laddas upp till Mastodon."; "Scene.Familiarfollowers.Title" = "Följare du liknar"; "Scene.Favorite.Title" = "Dina favoriter"; "Scene.FavoritedBy.Title" = "Favoriserad av"; +"Scene.FollowedTags.Actions.Follow" = "Följ"; +"Scene.FollowedTags.Actions.Unfollow" = "Avfölj"; +"Scene.FollowedTags.Header.Participants" = "deltagare"; +"Scene.FollowedTags.Header.Posts" = "inlägg"; +"Scene.FollowedTags.Header.PostsToday" = "inlägg idag"; +"Scene.FollowedTags.Title" = "Följda hashtaggar"; "Scene.Follower.Footer" = "Följare från andra servrar visas inte."; "Scene.Follower.Title" = "följare"; "Scene.Following.Footer" = "Följda på andra servrar visas inte."; @@ -268,6 +287,7 @@ laddas upp till Mastodon."; "Scene.Profile.Dashboard.Following" = "följer"; "Scene.Profile.Dashboard.Posts" = "inlägg"; "Scene.Profile.Fields.AddRow" = "Lägg till rad"; +"Scene.Profile.Fields.Joined" = "Gick med"; "Scene.Profile.Fields.Placeholder.Content" = "Innehåll"; "Scene.Profile.Fields.Placeholder.Label" = "Etikett"; "Scene.Profile.Fields.Verified.Long" = "Ägarskap för denna länk kontrollerades den %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict index 3cbfeae6d..43a0ff8e4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict @@ -280,7 +280,7 @@ NSStringFormatValueTypeKey ld one - %ld år kvar + 1 år kvar other %ld år kvar @@ -296,7 +296,7 @@ NSStringFormatValueTypeKey ld one - %ld månad kvar + 1 månad kvar other %ld månader kvar @@ -312,7 +312,7 @@ NSStringFormatValueTypeKey ld one - %ld dag kvar + 1 dag kvar other %ld dagar kvar @@ -360,7 +360,7 @@ NSStringFormatValueTypeKey ld one - %ld sekund kvar + 1 sekund kvar other %ld sekunder kvar @@ -408,7 +408,7 @@ NSStringFormatValueTypeKey ld one - %ldd sedan + 1d sedan other %ldd sedan @@ -424,7 +424,7 @@ NSStringFormatValueTypeKey ld one - %ldt sedan + 1t sedan other %ldt sedan diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index 25c7e37f8..6aeeb2a74 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "คุณแน่ใจหรือไม่ว่าต้องการลงชื่อออก?"; "Common.Alerts.SignOut.Title" = "ลงชื่อออก"; "Common.Alerts.SignUpFailure.Title" = "การลงทะเบียนล้มเหลว"; +"Common.Alerts.TranslationFailed.Button" = "ตกลง"; +"Common.Alerts.TranslationFailed.Message" = "การแปลล้มเหลว บางทีผู้ดูแลอาจไม่ได้เปิดใช้งานการแปลในเซิร์ฟเวอร์นี้หรือเซิร์ฟเวอร์นี้กำลังใช้ Mastodon รุ่นเก่ากว่าที่ยังไม่รองรับการแปล"; +"Common.Alerts.TranslationFailed.Title" = "หมายเหตุ"; "Common.Alerts.VoteFailure.PollEnded" = "การสำรวจความคิดเห็นได้สิ้นสุดแล้ว"; "Common.Alerts.VoteFailure.Title" = "การลงคะแนนล้มเหลว"; "Common.Controls.Actions.Add" = "เพิ่ม"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "เขียน"; "Common.Controls.Actions.Confirm" = "ยืนยัน"; "Common.Controls.Actions.Continue" = "ดำเนินการต่อ"; +"Common.Controls.Actions.Copy" = "คัดลอก"; "Common.Controls.Actions.CopyPhoto" = "คัดลอกรูปภาพ"; "Common.Controls.Actions.Delete" = "ลบ"; "Common.Controls.Actions.Discard" = "ละทิ้ง"; @@ -59,6 +63,8 @@ "Common.Controls.Actions.SignUp" = "สร้างบัญชี"; "Common.Controls.Actions.Skip" = "ข้าม"; "Common.Controls.Actions.TakePhoto" = "ถ่ายรูป"; +"Common.Controls.Actions.TranslatePost.Title" = "แปลจาก %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "ไม่รู้จัก"; "Common.Controls.Actions.TryAgain" = "ลองอีกครั้ง"; "Common.Controls.Actions.UnblockDomain" = "เลิกปิดกั้น %@"; "Common.Controls.Friendship.Block" = "ปิดกั้น"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "เมนู"; "Common.Controls.Status.Actions.Reblog" = "ดัน"; "Common.Controls.Status.Actions.Reply" = "ตอบกลับ"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "แบ่งปันลิงก์ในโพสต์"; "Common.Controls.Status.Actions.ShowGif" = "แสดง GIF"; "Common.Controls.Status.Actions.ShowImage" = "แสดงภาพ"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "แสดงตัวเล่นวิดีโอ"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "เลิกชื่นชอบ"; "Common.Controls.Status.Actions.Unreblog" = "เลิกทำการดัน"; "Common.Controls.Status.ContentWarning" = "คำเตือนเนื้อหา"; +"Common.Controls.Status.LinkViaUser" = "%@ ผ่าน %@"; +"Common.Controls.Status.LoadEmbed" = "โหลดที่ฝังไว้"; "Common.Controls.Status.MediaContentWarning" = "แตะที่ใดก็ตามเพื่อเปิดเผย"; "Common.Controls.Status.MetaEntity.Email" = "ที่อยู่อีเมล: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "แฮชแท็ก: %@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "กล่าวถึง"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "แตะเพื่อเปิดเผย"; +"Common.Controls.Status.Translation.ShowOriginal" = "แสดงดั้งเดิมอยู่"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "ไม่รู้จัก"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ ได้ดัน"; "Common.Controls.Status.UserRepliedTo" = "ตอบกลับ %@"; "Common.Controls.Status.Visibility.Direct" = "เฉพาะผู้ใช้ที่กล่าวถึงเท่านั้นที่สามารถเห็นโพสต์นี้"; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "เฉพาะผู้ติดตามของฉันเท่านั้นที่สามารถเห็นโพสต์นี้"; "Common.Controls.Status.Visibility.Unlisted" = "ทุกคนสามารถเห็นโพสต์นี้แต่ไม่แสดงในเส้นเวลาสาธารณะ"; "Common.Controls.Tabs.Home" = "หน้าแรก"; -"Common.Controls.Tabs.Notification" = "การแจ้งเตือน"; +"Common.Controls.Tabs.Notifications" = "การแจ้งเตือน"; "Common.Controls.Tabs.Profile" = "โปรไฟล์"; -"Common.Controls.Tabs.Search" = "ค้นหา"; +"Common.Controls.Tabs.SearchAndExplore" = "ค้นหาและสำรวจ"; "Common.Controls.Timeline.Filtered" = "กรองอยู่"; "Common.Controls.Timeline.Header.BlockedWarning" = "คุณไม่สามารถดูโปรไฟล์ของผู้ใช้นี้ จนกว่าเขาจะเลิกปิดกั้นคุณ"; @@ -229,6 +242,12 @@ "Scene.Familiarfollowers.Title" = "ผู้ติดตามที่คุณคุ้นเคย"; "Scene.Favorite.Title" = "รายการโปรดของคุณ"; "Scene.FavoritedBy.Title" = "ชื่นชอบโดย"; +"Scene.FollowedTags.Actions.Follow" = "ติดตาม"; +"Scene.FollowedTags.Actions.Unfollow" = "เลิกติดตาม"; +"Scene.FollowedTags.Header.Participants" = "ผู้เข้าร่วม"; +"Scene.FollowedTags.Header.Posts" = "โพสต์"; +"Scene.FollowedTags.Header.PostsToday" = "โพสต์วันนี้"; +"Scene.FollowedTags.Title" = "แท็กที่ติดตาม"; "Scene.Follower.Footer" = "ไม่ได้แสดงผู้ติดตามจากเซิร์ฟเวอร์อื่น ๆ"; "Scene.Follower.Title" = "ผู้ติดตาม"; "Scene.Following.Footer" = "ไม่ได้แสดงการติดตามจากเซิร์ฟเวอร์อื่น ๆ"; @@ -268,6 +287,7 @@ "Scene.Profile.Dashboard.Following" = "กำลังติดตาม"; "Scene.Profile.Dashboard.Posts" = "โพสต์"; "Scene.Profile.Fields.AddRow" = "เพิ่มแถว"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "เนื้อหา"; "Scene.Profile.Fields.Placeholder.Label" = "ป้ายชื่อ"; "Scene.Profile.Fields.Verified.Long" = "ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index fcee4e12e..c71fb332e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -21,6 +21,9 @@ "Common.Alerts.SignOut.Message" = "Oturumu kapatmak istediğinize emin misiniz?"; "Common.Alerts.SignOut.Title" = "Oturumu Kapat"; "Common.Alerts.SignUpFailure.Title" = "Kaydolma Başarısız"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Anket bitti"; "Common.Alerts.VoteFailure.Title" = "Oy Verme Başarısız"; "Common.Controls.Actions.Add" = "Ekle"; @@ -30,6 +33,7 @@ "Common.Controls.Actions.Compose" = "Yaz"; "Common.Controls.Actions.Confirm" = "Onayla"; "Common.Controls.Actions.Continue" = "Devam et"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "Fotoğrafı Kopyala"; "Common.Controls.Actions.Delete" = "Sil"; "Common.Controls.Actions.Discard" = "Vazgeç"; @@ -54,10 +58,12 @@ "Common.Controls.Actions.Share" = "Paylaş"; "Common.Controls.Actions.SharePost" = "Gönderiyi Paylaş"; "Common.Controls.Actions.ShareUser" = "%@ ile paylaş"; -"Common.Controls.Actions.SignIn" = "Log in"; -"Common.Controls.Actions.SignUp" = "Create account"; +"Common.Controls.Actions.SignIn" = "Giriş Yap"; +"Common.Controls.Actions.SignUp" = "Hesap oluştur"; "Common.Controls.Actions.Skip" = "Atla"; "Common.Controls.Actions.TakePhoto" = "Fotoğraf Çek"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Tekrar Deneyin"; "Common.Controls.Actions.UnblockDomain" = "%@ kişisinin engelini kaldır"; "Common.Controls.Friendship.Block" = "Engelle"; @@ -67,13 +73,13 @@ "Common.Controls.Friendship.EditInfo" = "Bilgiyi Düzenle"; "Common.Controls.Friendship.Follow" = "Takip et"; "Common.Controls.Friendship.Following" = "Takip ediliyor"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; +"Common.Controls.Friendship.HideReblogs" = "Yeniden Paylaşımları Gizle"; "Common.Controls.Friendship.Mute" = "Sessize al"; "Common.Controls.Friendship.MuteUser" = "Sustur %@"; "Common.Controls.Friendship.Muted" = "Susturuldu"; "Common.Controls.Friendship.Pending" = "Bekliyor"; "Common.Controls.Friendship.Request" = "İstek"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; +"Common.Controls.Friendship.ShowReblogs" = "Yeniden Paylaşımları Göster"; "Common.Controls.Friendship.Unblock" = "Engeli kaldır"; "Common.Controls.Friendship.UnblockUser" = "%@ kişisinin engelini kaldır"; "Common.Controls.Friendship.Unmute" = "Susturmayı kaldır"; @@ -99,6 +105,7 @@ "Common.Controls.Status.Actions.Menu" = "Menü"; "Common.Controls.Status.Actions.Reblog" = "Yeniden paylaş"; "Common.Controls.Status.Actions.Reply" = "Yanıtla"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "GIF'i göster"; "Common.Controls.Status.Actions.ShowImage" = "Görüntüyü göster"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Video oynatıcıyı göster"; @@ -106,11 +113,13 @@ "Common.Controls.Status.Actions.Unfavorite" = "Favorilerden Çıkar"; "Common.Controls.Status.Actions.Unreblog" = "Yeniden paylaşımı geri al"; "Common.Controls.Status.ContentWarning" = "İçerik Uyarısı"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "Göstermek için herhangi bir yere basın"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; -"Common.Controls.Status.MetaEntity.Url" = "Link: %@"; +"Common.Controls.Status.MetaEntity.Email" = "E-posta adresi: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Etiket: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Profili Göster: %@"; +"Common.Controls.Status.MetaEntity.Url" = "Bağlantı: %@"; "Common.Controls.Status.Poll.Closed" = "Kapandı"; "Common.Controls.Status.Poll.Vote" = "Oy ver"; "Common.Controls.Status.SensitiveContent" = "Hassas İçerik"; @@ -123,6 +132,10 @@ "Common.Controls.Status.Tag.Mention" = "Bahset"; "Common.Controls.Status.Tag.Url" = "Bağlantı"; "Common.Controls.Status.TapToReveal" = "Göstermek için basın"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ yeniden paylaştı"; "Common.Controls.Status.UserRepliedTo" = "%@ kullanıcısına yanıt verdi"; "Common.Controls.Status.Visibility.Direct" = "Sadece bahsedilen kullanıcı bu gönderiyi görebilir."; @@ -130,9 +143,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "Sadece benim takipçilerim bu gönderiyi görebilir."; "Common.Controls.Status.Visibility.Unlisted" = "Bu gönderiyi herkes görebilir, fakat herkese açık zaman tünelinde gösterilmez."; "Common.Controls.Tabs.Home" = "Ana Sayfa"; -"Common.Controls.Tabs.Notification" = "Bildirimler"; +"Common.Controls.Tabs.Notifications" = "Bildirimler"; "Common.Controls.Tabs.Profile" = "Profil"; -"Common.Controls.Tabs.Search" = "Arama"; +"Common.Controls.Tabs.SearchAndExplore" = "Ara ve Keşfet"; "Common.Controls.Timeline.Filtered" = "Filtrelenmiş"; "Common.Controls.Timeline.Header.BlockedWarning" = "Bu kişi sizin engelinizi kaldırana kadar onun profilini göremezsiniz."; @@ -154,27 +167,27 @@ Bu kişiye göre profiliniz böyle gözüküyor."; "Scene.AccountList.AddAccount" = "Hesap Ekle"; "Scene.AccountList.DismissAccountSwitcher" = "Hesap Değiştiriciyi Kapat"; "Scene.AccountList.TabBarHint" = "Şu anki seçili profil: %@. Hesap değiştiriciyi göstermek için iki kez dokunun ve basılı tutun"; -"Scene.Bookmark.Title" = "Bookmarks"; +"Scene.Bookmark.Title" = "Yer İmleri"; "Scene.Compose.Accessibility.AppendAttachment" = "Dosya Ekle"; "Scene.Compose.Accessibility.AppendPoll" = "Anket Ekle"; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Özel Emoji Seçici"; "Scene.Compose.Accessibility.DisableContentWarning" = "İçerik Uyarısını Kapat"; "Scene.Compose.Accessibility.EnableContentWarning" = "İçerik Uyarısını Etkinleştir"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; +"Scene.Compose.Accessibility.PostOptions" = "Gönderi Seçenekleri"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Gönderi Görünürlüğü Menüsü"; -"Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; +"Scene.Compose.Accessibility.PostingAs" = "%@ olarak paylaşılıyor"; "Scene.Compose.Accessibility.RemovePoll" = "Anketi Kaldır"; "Scene.Compose.Attachment.AttachmentBroken" = "Bu %@ bozuk ve Mastodon'a yüklenemiyor."; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; -"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; -"Scene.Compose.Attachment.CompressingState" = "Compressing..."; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Ek boyutu çok büyük"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Ekteki medya uzantısı görüntülenemiyor"; +"Scene.Compose.Attachment.CompressingState" = "Sıkıştırılıyor..."; "Scene.Compose.Attachment.DescriptionPhoto" = "Görme engelliler için fotoğrafı tarif edin..."; "Scene.Compose.Attachment.DescriptionVideo" = "Görme engelliler için videoyu tarif edin..."; -"Scene.Compose.Attachment.LoadFailed" = "Load Failed"; +"Scene.Compose.Attachment.LoadFailed" = "Yükleme Başarısız"; "Scene.Compose.Attachment.Photo" = "fotoğraf"; -"Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; +"Scene.Compose.Attachment.ServerProcessingState" = "Sunucu İşliyor..."; +"Scene.Compose.Attachment.UploadFailed" = "Yükleme Başarısız"; "Scene.Compose.Attachment.Video" = "video"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Eklemek için boşluk tuşuna basın"; "Scene.Compose.ComposeAction" = "Yayınla"; @@ -196,7 +209,7 @@ yüklenemiyor."; "Scene.Compose.Poll.SevenDays" = "7 Gün"; "Scene.Compose.Poll.SixHours" = "6 Saat"; "Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; -"Scene.Compose.Poll.ThePollIsInvalid" = "The poll is invalid"; +"Scene.Compose.Poll.ThePollIsInvalid" = "Anket geçersiz"; "Scene.Compose.Poll.ThirtyMinutes" = "30 dakika"; "Scene.Compose.Poll.ThreeDays" = "3 Gün"; "Scene.Compose.ReplyingToUser" = "yanıtlanıyor: %@"; @@ -224,10 +237,16 @@ yüklenemiyor."; "Scene.Discovery.Tabs.Hashtags" = "Etiketler"; "Scene.Discovery.Tabs.News" = "Haberler"; "Scene.Discovery.Tabs.Posts" = "Gönderiler"; -"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; -"Scene.Familiarfollowers.Title" = "Followers you familiar"; +"Scene.Familiarfollowers.FollowedByNames" = "%@ tarafından takip ediliyor"; +"Scene.Familiarfollowers.Title" = "Tanıyor olabileceğin takipçiler"; "Scene.Favorite.Title" = "Favorilerin"; "Scene.FavoritedBy.Title" = "Favorited By"; +"Scene.FollowedTags.Actions.Follow" = "Takip et"; +"Scene.FollowedTags.Actions.Unfollow" = "Takibi bırak"; +"Scene.FollowedTags.Header.Participants" = "katılımcılar"; +"Scene.FollowedTags.Header.Posts" = "gönderiler"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Takip Edilen Etiketler"; "Scene.Follower.Footer" = "Diğer sunucudaki takipçiler gösterilemiyor."; "Scene.Follower.Title" = "takipçi"; "Scene.Following.Footer" = "Diğer sunucudaki takip edilenler gösterilemiyor."; @@ -239,13 +258,13 @@ yüklenemiyor."; "Scene.HomeTimeline.NavigationBarState.Published" = "Yayınlandı!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "Gönderi yayınlanıyor..."; "Scene.HomeTimeline.Title" = "Ana Sayfa"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; -"Scene.Notification.FollowRequest.Accept" = "Accept"; -"Scene.Notification.FollowRequest.Accepted" = "Accepted"; -"Scene.Notification.FollowRequest.Reject" = "reject"; -"Scene.Notification.FollowRequest.Rejected" = "Rejected"; +"Scene.Login.ServerSearchField.Placeholder" = "Bir URL girin ya da sunucunuzu arayın"; +"Scene.Login.Subtitle" = "Hesabını oluşturduğun sunucuya giriş yap."; +"Scene.Login.Title" = "Tekrar hoş geldin"; +"Scene.Notification.FollowRequest.Accept" = "Kabul Et"; +"Scene.Notification.FollowRequest.Accepted" = "Kabul Edildi"; +"Scene.Notification.FollowRequest.Reject" = "Reddet"; +"Scene.Notification.FollowRequest.Rejected" = "Reddedildi"; "Scene.Notification.Keyobard.ShowEverything" = "Her Şeyi Göster"; "Scene.Notification.Keyobard.ShowMentions" = "Bahsetmeleri Göster"; "Scene.Notification.NotificationDescription.FavoritedYourPost" = "gönderini favoriledi"; @@ -267,19 +286,20 @@ yüklenemiyor."; "Scene.Profile.Dashboard.Following" = "takip ediliyor"; "Scene.Profile.Dashboard.Posts" = "gönderiler"; "Scene.Profile.Fields.AddRow" = "Satır Ekle"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "İçerik"; "Scene.Profile.Fields.Placeholder.Label" = "Etiket"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; -"Scene.Profile.Fields.Verified.Short" = "Verified on %@"; +"Scene.Profile.Fields.Verified.Long" = "%@ adresinin sahipliği kontrol edilmiş"; +"Scene.Profile.Fields.Verified.Short" = "%@ tarafında onaylı"; "Scene.Profile.Header.FollowsYou" = "Seni takip ediyor"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "%@ engellemeyi onayla"; "Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Hesabı Engelle"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Yeniden paylaşımları gizlemeyi onayla"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Yeniden Paylaşımları Gizle"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "%@ susturmak için onaylayın"; "Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Hesabı sustur"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Yeniden paylaşımları göstermeyi onayla"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Yeniden Paylaşımları Göster"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "%@ engellemeyi kaldırmayı onaylayın"; "Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Hesabın Engelini Kaldır"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "%@ susturmasını kaldırmak için onaylayın"; @@ -332,15 +352,15 @@ yüklenemiyor."; "Scene.Report.SkipToSend" = "Yorum yapmadan gönder"; "Scene.Report.Step1" = "Adım 1/2"; "Scene.Report.Step2" = "Adım 2/2"; -"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.BlockUser" = "%@ kişisini engelle"; "Scene.Report.StepFinal.DontWantToSeeThis" = "Bunu görmek istemiyor musunuz?"; "Scene.Report.StepFinal.MuteUser" = "Sustur %@"; -"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Artık sizi takip edemez ve gönderilerinizi göremezler ama engellendiklerini görebilirler."; "Scene.Report.StepFinal.Unfollow" = "Takibi bırak"; "Scene.Report.StepFinal.UnfollowUser" = "Takipten çık %@"; -"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; -"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; -"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.Unfollowed" = "Takipten çıkıldı"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Mastodon'da beğenmediğiniz bir şey gördüğünüzde, o kişiyi deneyiminizden çıkarabilirsiniz."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Biz bunu incelerken siz %@ hesabına karşı önlem alabilirsiniz"; "Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; "Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Bilmemiz gereken başka bir şey var mı?"; "Scene.Report.StepFour.Step4Of4" = "Adım 4/4"; @@ -349,14 +369,14 @@ yüklenemiyor."; "Scene.Report.StepOne.ItViolatesServerRules" = "Sunucu kurallarını ihlal ediyor"; "Scene.Report.StepOne.ItsSomethingElse" = "Başka bir şey"; "Scene.Report.StepOne.ItsSpam" = "Spam"; -"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Kötü niyetli bağlantılar, sahte etkileşim veya tekrarlayan yanıtlar"; "Scene.Report.StepOne.SelectTheBestMatch" = "En iyi seçeneceği seçiniz"; "Scene.Report.StepOne.Step1Of4" = "Adım 1/4"; "Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Sorun bunlardan biri değil"; "Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Bu hesap ile ilgili sorun nedir?"; "Scene.Report.StepOne.WhatsWrongWithThisPost" = "Bu gönderi ile ilgili sorun nedir?"; "Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@ kişisinin sorunu nedir?"; -"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Belirli kuralları ihlal ettiğinin farkındasınız"; "Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Bu bildirimi destekleyecek herhangi bir gönderi var mı?"; "Scene.Report.StepThree.SelectAllThatApply" = "Geçerli olanların tümünü seçiniz"; "Scene.Report.StepThree.Step3Of4" = "Adım 3/4"; @@ -403,11 +423,11 @@ yüklenemiyor."; "Scene.ServerPicker.EmptyState.BadNetwork" = "Veriyi yüklerken bir hata oluştu. Lütfen internet bağlantınızı kontrol edin."; "Scene.ServerPicker.EmptyState.FindingServers" = "Mevcut sunucular aranıyor..."; "Scene.ServerPicker.EmptyState.NoResults" = "Sonuç yok"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Topluluklar arayın ya da bir URL girin"; "Scene.ServerPicker.Label.Category" = "KATEGORİ"; "Scene.ServerPicker.Label.Language" = "DİL"; "Scene.ServerPicker.Label.Users" = "KULLANICILAR"; -"Scene.ServerPicker.Subtitle" = "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers."; +"Scene.ServerPicker.Subtitle" = "Bölgenize dayalı, ilginize dayalı ya da genel amaçlı bir sunucu seçin. Hangi sunucuda olduğunuz fark etmeksizin Mastodon'daki herkes ile konuşabilirsiniz."; "Scene.ServerPicker.Title" = "Mastodon, farklı topluluklardaki kullanıcılardan oluşur."; "Scene.ServerRules.Button.Confirm" = "Kabul Ediyorum"; "Scene.ServerRules.PrivacyPolicy" = "gizlilik politikası"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict index 6ef7f4c75..13552b607 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict @@ -53,7 +53,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ kaldı character_count NSStringFormatSpecTypeKey @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 karakter other - %ld characters + %ld karakter plural.count.followed_by_and_mutual @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + %1$@ ve bir ortak kişi tarafından takip edildi other - Followed by %1$@, and %ld mutuals + %1$@ ve %ld ortak kişi tarafından takip edildi plural.count.metric_formatted.post @@ -120,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 media + 1 medya other - %ld media + %ld medya plural.count.post diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index 5a14fb2cf..dc66003cc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -22,6 +22,9 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Alerts.SignOut.Message" = "Bạn có chắc muốn đăng xuất không?"; "Common.Alerts.SignOut.Title" = "Đăng xuất"; "Common.Alerts.SignUpFailure.Title" = "Đăng ký không thành công"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Dịch không thành công. Có thể quản trị viên chưa bật dịch trên máy chủ này hoặc máy chủ này đang chạy phiên bản cũ hơn của Mastodon chưa hỗ trợ dịch."; +"Common.Alerts.TranslationFailed.Title" = "Ghi chú"; "Common.Alerts.VoteFailure.PollEnded" = "Cuộc bình chọn đã kết thúc"; "Common.Alerts.VoteFailure.Title" = "Bình chọn không thành công"; "Common.Controls.Actions.Add" = "Thêm"; @@ -31,6 +34,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.Compose" = "Viết tút"; "Common.Controls.Actions.Confirm" = "Xác nhận"; "Common.Controls.Actions.Continue" = "Tiếp tục"; +"Common.Controls.Actions.Copy" = "Chép"; "Common.Controls.Actions.CopyPhoto" = "Sao chép ảnh"; "Common.Controls.Actions.Delete" = "Xóa"; "Common.Controls.Actions.Discard" = "Bỏ qua"; @@ -59,6 +63,8 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.SignUp" = "Tạo tài khoản"; "Common.Controls.Actions.Skip" = "Bỏ qua"; "Common.Controls.Actions.TakePhoto" = "Chụp ảnh"; +"Common.Controls.Actions.TranslatePost.Title" = "Dịch từ %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Chưa xác định"; "Common.Controls.Actions.TryAgain" = "Thử lại"; "Common.Controls.Actions.UnblockDomain" = "Bỏ chặn %@"; "Common.Controls.Friendship.Block" = "Chặn"; @@ -100,6 +106,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.Actions.Menu" = "Menu"; "Common.Controls.Status.Actions.Reblog" = "Đăng lại"; "Common.Controls.Status.Actions.Reply" = "Trả lời"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Chia sẻ liên kết trong Tút"; "Common.Controls.Status.Actions.ShowGif" = "Hiển thị GIF"; "Common.Controls.Status.Actions.ShowImage" = "Hiển thị hình ảnh"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Hiện trình phát video"; @@ -107,6 +114,8 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.Actions.Unfavorite" = "Bỏ thích"; "Common.Controls.Status.Actions.Unreblog" = "Hủy đăng lại"; "Common.Controls.Status.ContentWarning" = "Nội dung ẩn"; +"Common.Controls.Status.LinkViaUser" = "%@ bởi %@"; +"Common.Controls.Status.LoadEmbed" = "Nạp mã nhúng"; "Common.Controls.Status.MediaContentWarning" = "Nhấn để hiển thị"; "Common.Controls.Status.MetaEntity.Email" = "Email: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; @@ -124,6 +133,10 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.Tag.Mention" = "Nhắc đến"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Nhấn để xem"; +"Common.Controls.Status.Translation.ShowOriginal" = "Bản gốc"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Không xác định"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ đăng lại"; "Common.Controls.Status.UserRepliedTo" = "Trả lời đến %@"; "Common.Controls.Status.Visibility.Direct" = "Chỉ người được nhắc đến có thể thấy tút."; @@ -131,9 +144,9 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Chỉ người theo dõi tôi có thể thấy tút này."; "Common.Controls.Status.Visibility.Unlisted" = "Ai cũng thấy tút này nhưng không hiện trên bảng tin máy chủ."; "Common.Controls.Tabs.Home" = "Bảng tin"; -"Common.Controls.Tabs.Notification" = "Thông báo"; +"Common.Controls.Tabs.Notifications" = "Thông báo"; "Common.Controls.Tabs.Profile" = "Trang hồ sơ"; -"Common.Controls.Tabs.Search" = "Tìm kiếm"; +"Common.Controls.Tabs.SearchAndExplore" = "Tìm và Khám Phá"; "Common.Controls.Timeline.Filtered" = "Bộ lọc"; "Common.Controls.Timeline.Header.BlockedWarning" = "Bạn không thể xem trang người này cho tới khi họ bỏ chặn bạn."; @@ -200,7 +213,7 @@ tải lên Mastodon."; "Scene.Compose.Poll.ThePollIsInvalid" = "Bình chọn không hợp lệ"; "Scene.Compose.Poll.ThirtyMinutes" = "30 phút"; "Scene.Compose.Poll.ThreeDays" = "3 ngày"; -"Scene.Compose.ReplyingToUser" = "trả lời %@"; +"Scene.Compose.ReplyingToUser" = "%@ viết tiếp"; "Scene.Compose.Title.NewPost" = "Viết tút"; "Scene.Compose.Title.NewReply" = "Viết trả lời"; "Scene.Compose.Visibility.Direct" = "Nhắn riêng"; @@ -229,6 +242,12 @@ tải lên Mastodon."; "Scene.Familiarfollowers.Title" = "Người theo dõi tương tự"; "Scene.Favorite.Title" = "Lượt thích"; "Scene.FavoritedBy.Title" = "Thích bởi"; +"Scene.FollowedTags.Actions.Follow" = "Theo dõi"; +"Scene.FollowedTags.Actions.Unfollow" = "Ngưng theo dõi"; +"Scene.FollowedTags.Header.Participants" = "người thảo luận"; +"Scene.FollowedTags.Header.Posts" = "tút"; +"Scene.FollowedTags.Header.PostsToday" = "tút hôm nay"; +"Scene.FollowedTags.Title" = "Hashtag Theo Dõi"; "Scene.Follower.Footer" = "Không hiển thị người theo dõi từ máy chủ khác."; "Scene.Follower.Title" = "người theo dõi"; "Scene.Following.Footer" = "Không hiển thị người bạn theo dõi từ máy chủ khác."; @@ -268,6 +287,7 @@ tải lên Mastodon."; "Scene.Profile.Dashboard.Following" = "theo dõi"; "Scene.Profile.Dashboard.Posts" = "tút"; "Scene.Profile.Fields.AddRow" = "Thêm hàng"; +"Scene.Profile.Fields.Joined" = "Đã tham gia"; "Scene.Profile.Fields.Placeholder.Content" = "Nội dung"; "Scene.Profile.Fields.Placeholder.Label" = "Nhãn"; "Scene.Profile.Fields.Verified.Long" = "Liên kết này đã được xác minh trên %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index 0c779d293..7d164f80e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "您确定要退出吗?"; "Common.Alerts.SignOut.Title" = "退出"; "Common.Alerts.SignUpFailure.Title" = "注册失败"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "投票已结束"; "Common.Alerts.VoteFailure.Title" = "投票失败"; "Common.Controls.Actions.Add" = "添加"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "撰写"; "Common.Controls.Actions.Confirm" = "确认"; "Common.Controls.Actions.Continue" = "继续"; +"Common.Controls.Actions.Copy" = "Copy"; "Common.Controls.Actions.CopyPhoto" = "拷贝照片"; "Common.Controls.Actions.Delete" = "删除"; "Common.Controls.Actions.Discard" = "放弃"; @@ -59,6 +63,8 @@ "Common.Controls.Actions.SignUp" = "创建账户"; "Common.Controls.Actions.Skip" = "跳过"; "Common.Controls.Actions.TakePhoto" = "拍照"; +"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "再试一次"; "Common.Controls.Actions.UnblockDomain" = "解除屏蔽 %@"; "Common.Controls.Friendship.Block" = "屏蔽"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "菜单"; "Common.Controls.Status.Actions.Reblog" = "转发"; "Common.Controls.Status.Actions.Reply" = "回复"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; "Common.Controls.Status.Actions.ShowGif" = "显示 GIF"; "Common.Controls.Status.Actions.ShowImage" = "显示图片"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "显示视频播放器"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "取消喜欢"; "Common.Controls.Status.Actions.Unreblog" = "取消转发"; "Common.Controls.Status.ContentWarning" = "内容警告"; +"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.LoadEmbed" = "Load Embed"; "Common.Controls.Status.MediaContentWarning" = "点击任意位置显示"; "Common.Controls.Status.MetaEntity.Email" = "邮箱地址:%@"; "Common.Controls.Status.MetaEntity.Hashtag" = "话题:%@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "提及"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "点击以显示"; +"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ 转发"; "Common.Controls.Status.UserRepliedTo" = "回复给 %@"; "Common.Controls.Status.Visibility.Direct" = "只有提到的用户才能看到此帖子。"; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "只有我的关注者才能看到此帖子。"; "Common.Controls.Status.Visibility.Unlisted" = "任何人都可以看到这个帖子,但不会在公开的时间线中显示。"; "Common.Controls.Tabs.Home" = "主页"; -"Common.Controls.Tabs.Notification" = "通知"; +"Common.Controls.Tabs.Notifications" = "通知"; "Common.Controls.Tabs.Profile" = "个人资料"; -"Common.Controls.Tabs.Search" = "搜索"; +"Common.Controls.Tabs.SearchAndExplore" = "Search and Explore"; "Common.Controls.Timeline.Filtered" = "已过滤"; "Common.Controls.Timeline.Header.BlockedWarning" = "您不能查看此用户的个人资料 直到他们解除屏蔽。"; @@ -229,6 +242,12 @@ "Scene.Familiarfollowers.Title" = "你熟悉的关注者"; "Scene.Favorite.Title" = "你的喜欢"; "Scene.FavoritedBy.Title" = "收藏者"; +"Scene.FollowedTags.Actions.Follow" = "Follow"; +"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; +"Scene.FollowedTags.Header.Participants" = "participants"; +"Scene.FollowedTags.Header.Posts" = "posts"; +"Scene.FollowedTags.Header.PostsToday" = "posts today"; +"Scene.FollowedTags.Title" = "Followed Tags"; "Scene.Follower.Footer" = "不会显示来自其它服务器的关注者"; "Scene.Follower.Title" = "关注者"; "Scene.Following.Footer" = "不会显示来自其它服务器的关注"; @@ -268,6 +287,7 @@ "Scene.Profile.Dashboard.Following" = "正在关注"; "Scene.Profile.Dashboard.Posts" = "帖子"; "Scene.Profile.Fields.AddRow" = "添加"; +"Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "内容"; "Scene.Profile.Fields.Placeholder.Label" = "标签"; "Scene.Profile.Fields.Verified.Long" = "此链接的所有权已在 %@ 上检查通过"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index 10dbbf8ca..eba0703c7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -22,6 +22,9 @@ "Common.Alerts.SignOut.Message" = "您確定要登出嗎?"; "Common.Alerts.SignOut.Title" = "登出"; "Common.Alerts.SignUpFailure.Title" = "註冊失敗"; +"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Message" = "翻譯失敗。也許管理員未於此伺服器啟用翻譯功能,或此伺服器為未支援翻譯功能之舊版本 Mastodon。"; +"Common.Alerts.TranslationFailed.Title" = "備註"; "Common.Alerts.VoteFailure.PollEnded" = "投票已結束"; "Common.Alerts.VoteFailure.Title" = "投票失敗"; "Common.Controls.Actions.Add" = "新增"; @@ -31,6 +34,7 @@ "Common.Controls.Actions.Compose" = "撰寫"; "Common.Controls.Actions.Confirm" = "確認"; "Common.Controls.Actions.Continue" = "繼續"; +"Common.Controls.Actions.Copy" = "複製"; "Common.Controls.Actions.CopyPhoto" = "複製照片"; "Common.Controls.Actions.Delete" = "刪除"; "Common.Controls.Actions.Discard" = "捨棄"; @@ -59,6 +63,8 @@ "Common.Controls.Actions.SignUp" = "新增帳號"; "Common.Controls.Actions.Skip" = "跳過"; "Common.Controls.Actions.TakePhoto" = "拍攝照片"; +"Common.Controls.Actions.TranslatePost.Title" = "翻譯自 %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "未知"; "Common.Controls.Actions.TryAgain" = "再試一次"; "Common.Controls.Actions.UnblockDomain" = "解除封鎖 %@"; "Common.Controls.Friendship.Block" = "封鎖"; @@ -100,6 +106,7 @@ "Common.Controls.Status.Actions.Menu" = "選單"; "Common.Controls.Status.Actions.Reblog" = "轉嘟"; "Common.Controls.Status.Actions.Reply" = "回覆"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "於嘟文中分享鏈結"; "Common.Controls.Status.Actions.ShowGif" = "顯示 GIF"; "Common.Controls.Status.Actions.ShowImage" = "顯示圖片"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "顯示影片播放器"; @@ -107,6 +114,8 @@ "Common.Controls.Status.Actions.Unfavorite" = "取消最愛"; "Common.Controls.Status.Actions.Unreblog" = "取消轉嘟"; "Common.Controls.Status.ContentWarning" = "內容警告"; +"Common.Controls.Status.LinkViaUser" = "%@ 透過 %@"; +"Common.Controls.Status.LoadEmbed" = "讀取嵌入內容"; "Common.Controls.Status.MediaContentWarning" = "輕觸任何地方以顯示"; "Common.Controls.Status.MetaEntity.Email" = "電子郵件地址:%@"; "Common.Controls.Status.MetaEntity.Hashtag" = "主題標籤: %@"; @@ -124,6 +133,10 @@ "Common.Controls.Status.Tag.Mention" = "提及"; "Common.Controls.Status.Tag.Url" = "網址"; "Common.Controls.Status.TapToReveal" = "輕觸以顯示"; +"Common.Controls.Status.Translation.ShowOriginal" = "顯示原文"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "未知"; +"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; "Common.Controls.Status.UserReblogged" = "%@ 已轉嘟"; "Common.Controls.Status.UserRepliedTo" = "回覆給 %@"; "Common.Controls.Status.Visibility.Direct" = "只有被提及的使用者能看到此嘟文。"; @@ -131,9 +144,9 @@ "Common.Controls.Status.Visibility.PrivateFromMe" = "只有我的跟隨者能看到此嘟文。"; "Common.Controls.Status.Visibility.Unlisted" = "任何人都能看到此嘟文,但是不會顯示於公開時間軸上。"; "Common.Controls.Tabs.Home" = "首頁"; -"Common.Controls.Tabs.Notification" = "通知"; +"Common.Controls.Tabs.Notifications" = "通知"; "Common.Controls.Tabs.Profile" = "個人檔案"; -"Common.Controls.Tabs.Search" = "搜尋"; +"Common.Controls.Tabs.SearchAndExplore" = "搜尋與探索"; "Common.Controls.Timeline.Filtered" = "已過濾"; "Common.Controls.Timeline.Header.BlockedWarning" = "您無法瀏覽該使用者的個人檔案,除非他們取消封鎖您。"; "Common.Controls.Timeline.Header.BlockingWarning" = "您無法瀏覽該使用者的個人檔案,除非您取消封鎖。 @@ -224,6 +237,12 @@ "Scene.Familiarfollowers.Title" = "您熟悉的跟隨者"; "Scene.Favorite.Title" = "您的最愛"; "Scene.FavoritedBy.Title" = "已加入最愛"; +"Scene.FollowedTags.Actions.Follow" = "跟隨"; +"Scene.FollowedTags.Actions.Unfollow" = "取消跟隨"; +"Scene.FollowedTags.Header.Participants" = "參與者"; +"Scene.FollowedTags.Header.Posts" = "嘟文"; +"Scene.FollowedTags.Header.PostsToday" = "本日嘟文"; +"Scene.FollowedTags.Title" = "已跟隨主題標籤"; "Scene.Follower.Footer" = "來自其他伺服器的跟隨者不會被顯示。"; "Scene.Follower.Title" = "跟隨者"; "Scene.Following.Footer" = "來自其他伺服器的跟隨中不會被顯示。"; @@ -263,6 +282,7 @@ "Scene.Profile.Dashboard.Following" = "跟隨中"; "Scene.Profile.Dashboard.Posts" = "嘟文"; "Scene.Profile.Fields.AddRow" = "新增列"; +"Scene.Profile.Fields.Joined" = "加入時間"; "Scene.Profile.Fields.Placeholder.Content" = "內容"; "Scene.Profile.Fields.Placeholder.Label" = "標籤"; "Scene.Profile.Fields.Verified.Long" = "已在 %@ 檢查此連結的擁有者權限"; From a7b0f30d088d299e4530d06e7f7598b784dbe085 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 19 Dec 2022 14:14:16 -0500 Subject: [PATCH 662/733] Fix status view not having actions from the menu --- MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index f64b0b225..c019d1406 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -611,7 +611,10 @@ extension StatusView { extension StatusView { public override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { - get { contentMetaText.textView.accessibilityCustomActions } + get { + (contentMetaText.textView.accessibilityCustomActions ?? []) + + (authorView.accessibilityCustomActions ?? []) + } set { } } } From 6ae1446a92f44a9f4e811843a06e96ead4b2ddd4 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 19 Dec 2022 14:53:00 -0500 Subject: [PATCH 663/733] Add reply/reblog/favorite actions to statuses --- .../View/Content/StatusView+ViewModel.swift | 43 ++++++++++++++++++- .../MastodonUI/View/Content/StatusView.swift | 6 ++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index aae8e0b66..3d261ba28 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -778,7 +778,48 @@ extension StatusView.ViewModel { return L10n.Plural.Count.media(count) } - // TODO: Toolbar + let replyLabel = $replyCount + .map { [L10n.Common.Controls.Actions.reply, L10n.Plural.Count.reply($0)] } + .map { $0.joined(separator: ", ") } + + let reblogLabel = Publishers.CombineLatest($isReblog, $reblogCount) + .map { isReblog, reblogCount in + [ + isReblog ? L10n.Common.Controls.Status.Actions.unreblog : L10n.Common.Controls.Status.Actions.reblog, + L10n.Plural.Count.reblog(reblogCount) + ] + } + .map { $0.joined(separator: ", ") } + + let favoriteLabel = Publishers.CombineLatest($isFavorite, $favoriteCount) + .map { isFavorite, favoriteCount in + [ + isFavorite ? L10n.Common.Controls.Status.Actions.unfavorite : L10n.Common.Controls.Status.Actions.favorite, + L10n.Plural.Count.favorite(favoriteCount) + ] + } + .map { $0.joined(separator: ", ") } + + Publishers.CombineLatest4(replyLabel, reblogLabel, $isReblogEnabled, favoriteLabel) + .map { replyLabel, reblogLabel, canReblog, favoriteLabel in + let toolbar = statusView.actionToolbarContainer + let replyAction = UIAccessibilityCustomAction(name: replyLabel) { _ in + statusView.actionToolbarContainer(toolbar, buttonDidPressed: toolbar.replyButton, action: .reply) + return true + } + let reblogAction = UIAccessibilityCustomAction(name: reblogLabel) { _ in + statusView.actionToolbarContainer(toolbar, buttonDidPressed: toolbar.reblogButton, action: .reblog) + return true + } + let favoriteAction = UIAccessibilityCustomAction(name: favoriteLabel) { _ in + statusView.actionToolbarContainer(toolbar, buttonDidPressed: toolbar.favoriteButton, action: .like) + return true + } + // (share, bookmark are excluded since they are already present in the “…” menu action set) + return canReblog ? [replyAction, reblogAction, favoriteAction] : [replyAction, favoriteAction] + } + .assign(to: \.toolbarActions, on: statusView) + .store(in: &disposeBag) Publishers.CombineLatest3( shortAuthorAccessibilityLabel, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index c019d1406..d2c5e75e7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -52,7 +52,10 @@ public final class StatusView: UIView { public weak var delegate: StatusViewDelegate? public private(set) var style: Style? - + + // accessibility actions + var toolbarActions = [UIAccessibilityCustomAction]() + public private(set) lazy var viewModel: ViewModel = { let viewModel = ViewModel() viewModel.bind(statusView: self) @@ -613,6 +616,7 @@ extension StatusView { public override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { get { (contentMetaText.textView.accessibilityCustomActions ?? []) + + toolbarActions + (authorView.accessibilityCustomActions ?? []) } set { } From a05b794090bc24e2097117fe6d8ba03105c38ed5 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 19 Dec 2022 15:17:46 -0500 Subject: [PATCH 664/733] Hide post contentMetaText when it is empty --- .../MastodonUI/View/Content/StatusView+ViewModel.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index aae8e0b66..09d8b825f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -314,16 +314,18 @@ extension StatusView.ViewModel { } statusView.contentMetaText.paragraphStyle = paragraphStyle - if let content = content { + if let content = content, !(content.string.isEmpty && content.entities.isEmpty) { statusView.contentMetaText.configure( content: content ) statusView.contentMetaText.textView.accessibilityTraits = [.staticText] statusView.contentMetaText.textView.accessibilityElementsHidden = false + statusView.contentMetaText.textView.isHidden = false } else { statusView.contentMetaText.reset() statusView.contentMetaText.textView.accessibilityLabel = "" + statusView.contentMetaText.textView.isHidden = true } statusView.contentMetaText.textView.alpha = isContentReveal ? 1 : 0 // keep the frame size and only display when revealing From eedc1a9dfd8568119cd30e4f323a504b08cb8dfa Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 20 Dec 2022 09:29:41 +0100 Subject: [PATCH 665/733] Bump version --- Mastodon.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 600d92258..44ec01f9b 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -3916,7 +3916,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.9; + MARKETING_VERSION = 1.4.10; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3945,7 +3945,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.9; + MARKETING_VERSION = 1.4.10; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4118,7 +4118,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.9; + MARKETING_VERSION = 1.4.10; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4401,7 +4401,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.9; + MARKETING_VERSION = 1.4.10; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From 0f28f9aedd3ceb33b8f7c2aff9b81e167aa1134a Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 20 Dec 2022 14:59:46 +0100 Subject: [PATCH 666/733] Temporarily downgrade python-version reason: https://github.com/codemagic-ci-cd/cli-tools/issues/293 --- .github/workflows/develop-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/develop-build.yml b/.github/workflows/develop-build.yml index ede061098..7dd9ebaab 100644 --- a/.github/workflows/develop-build.yml +++ b/.github/workflows/develop-build.yml @@ -24,7 +24,7 @@ jobs: - name: Install codemagic-cli-tools uses: actions/setup-python@v4 with: - python-version: '3.11' + python-version: '3.10' - run: | pip3 install codemagic-cli-tools - run: | From dd95724d140be1736d2da622c015450fe54c2078 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 24 Nov 2022 14:28:39 -0500 Subject: [PATCH 667/733] Factor out code for the close button --- Mastodon.xcodeproj/project.pbxproj | 4 ++ Mastodon/Scene/MediaPreview/HUDButton.swift | 59 +++++++++++++++++++ .../MediaPreviewViewController.swift | 47 +++------------ ...wViewControllerAnimatedTransitioning.swift | 10 ++-- 4 files changed, 77 insertions(+), 43 deletions(-) create mode 100644 Mastodon/Scene/MediaPreview/HUDButton.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 74b7841a5..aca99ccfb 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -98,6 +98,7 @@ 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; }; 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; + 85BC11B1292FF92C00E191CD /* HUDButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B0292FF92C00E191CD /* HUDButton.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; @@ -620,6 +621,7 @@ 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; + 85BC11B0292FF92C00E191CD /* HUDButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDButton.swift; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = ""; }; 8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = ""; }; @@ -1974,6 +1976,7 @@ DBB45B5727B39FCC002DC5A7 /* Video */, DB6180F026391CAB0018D199 /* Image */, DB6180E1263919780018D199 /* Paging */, + 85BC11B0292FF92C00E191CD /* HUDButton.swift */, DB6180DC263918E30018D199 /* MediaPreviewViewController.swift */, DB6180F926391F2E0018D199 /* MediaPreviewViewModel.swift */, ); @@ -3419,6 +3422,7 @@ 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */, 2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */, DB852D1C26FB021500FC9D81 /* RootSplitViewController.swift in Sources */, + 85BC11B1292FF92C00E191CD /* HUDButton.swift in Sources */, DB697DD1278F4871004EF2F7 /* AutoGenerateTableViewDelegate.swift in Sources */, DB02CDBF2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift in Sources */, DB3E6FFA2807C47900B035AE /* DiscoveryForYouViewModel+Diffable.swift in Sources */, diff --git a/Mastodon/Scene/MediaPreview/HUDButton.swift b/Mastodon/Scene/MediaPreview/HUDButton.swift new file mode 100644 index 000000000..b08f95eb4 --- /dev/null +++ b/Mastodon/Scene/MediaPreview/HUDButton.swift @@ -0,0 +1,59 @@ +// +// HUDButton.swift +// Mastodon +// +// Created by Jed Fox on 2022-11-24. +// + +import UIKit +import MastodonUI + +class HUDButton: UIView { + + static let height: CGFloat = 30 + + let background: UIVisualEffectView = { + let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)) + backgroundView.alpha = 0.9 + backgroundView.layer.masksToBounds = true + backgroundView.layer.cornerRadius = HUDButton.height * 0.5 + return backgroundView + }() + + let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemUltraThinMaterial))) + + let button: UIButton = { + let button = HighlightDimmableButton() + button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) + button.imageView?.tintColor = .label + return button + }() + + init(configure: (UIButton) -> Void) { + super.init(frame: .zero) + + configure(button) + _init() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + _init() + } + + func _init() { + translatesAutoresizingMaskIntoConstraints = false + background.translatesAutoresizingMaskIntoConstraints = false + addSubview(background) + background.pinToParent() + vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + background.contentView.addSubview(vibrancyView) + + button.translatesAutoresizingMaskIntoConstraints = false + vibrancyView.contentView.addSubview(button) + button.pinToParent() + NSLayoutConstraint.activate([ + heightAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), + ]) + } +} diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index dee6c00ea..c25d099a0 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -16,8 +16,6 @@ import MastodonLocalization final class MediaPreviewViewController: UIViewController, NeedsDependency { - static let closeButtonSize = CGSize(width: 30, height: 30) - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } @@ -27,23 +25,9 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency { let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) let pagingViewController = MediaPreviewPagingViewController() - let closeButtonBackground: UIVisualEffectView = { - let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)) - backgroundView.alpha = 0.9 - backgroundView.layer.masksToBounds = true - backgroundView.layer.cornerRadius = MediaPreviewViewController.closeButtonSize.width * 0.5 - return backgroundView - }() - - let closeButtonBackgroundVisualEffectView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemUltraThinMaterial))) - - let closeButton: UIButton = { - let button = HighlightDimmableButton() - button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) - button.imageView?.tintColor = .label + let closeButton = HUDButton { button in button.setImage(UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 16, weight: .bold))!, for: .normal) - return button - }() + } deinit { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) @@ -67,25 +51,12 @@ extension MediaPreviewViewController { visualEffectView.contentView.addSubview(pagingViewController.view) visualEffectView.pinTo(to: pagingViewController.view) pagingViewController.didMove(toParent: self) - - closeButtonBackground.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(closeButtonBackground) - NSLayoutConstraint.activate([ - closeButtonBackground.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), - closeButtonBackground.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor) - ]) - closeButtonBackgroundVisualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - closeButtonBackground.contentView.addSubview(closeButtonBackgroundVisualEffectView) - closeButton.translatesAutoresizingMaskIntoConstraints = false - closeButtonBackgroundVisualEffectView.contentView.addSubview(closeButton) + view.addSubview(closeButton) NSLayoutConstraint.activate([ - closeButton.topAnchor.constraint(equalTo: closeButtonBackgroundVisualEffectView.topAnchor), - closeButton.leadingAnchor.constraint(equalTo: closeButtonBackgroundVisualEffectView.leadingAnchor), - closeButtonBackgroundVisualEffectView.trailingAnchor.constraint(equalTo: closeButton.trailingAnchor), - closeButtonBackgroundVisualEffectView.bottomAnchor.constraint(equalTo: closeButton.bottomAnchor), - closeButton.heightAnchor.constraint(equalToConstant: MediaPreviewViewController.closeButtonSize.height).priority(.defaultHigh), - closeButton.widthAnchor.constraint(equalToConstant: MediaPreviewViewController.closeButtonSize.width).priority(.defaultHigh), + closeButton.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), + closeButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor), + closeButton.widthAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), ]) viewModel.mediaPreviewImageViewControllerDelegate = self @@ -94,7 +65,7 @@ extension MediaPreviewViewController { pagingViewController.delegate = self pagingViewController.dataSource = viewModel - closeButton.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside) + closeButton.button.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside) // bind view model viewModel.$currentPage @@ -126,7 +97,7 @@ extension MediaPreviewViewController { let attachment = previewContext.attachments[index] return attachment.kind == .video // not hide buttno for audio }() - self.closeButtonBackground.isHidden = needsHideCloseButton + self.closeButton.isHidden = needsHideCloseButton default: break } @@ -139,7 +110,7 @@ extension MediaPreviewViewController { .sink { [weak self] showingChrome in UIView.animate(withDuration: 0.3) { self?.setNeedsStatusBarAppearanceUpdate() - self?.closeButtonBackground.alpha = showingChrome ? 1 : 0 + self?.closeButton.alpha = showingChrome ? 1 : 0 } } .store(in: &disposeBag) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index ace6048c5..7bf81f0b0 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -81,7 +81,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { transitionItem.transitionView = transitionImageView transitionContext.containerView.addSubview(transitionImageView) - toVC.closeButtonBackground.alpha = 0 + toVC.closeButton.alpha = 0 if UIAccessibility.isReduceTransparencyEnabled { toVC.visualEffectView.alpha = 0 @@ -101,7 +101,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { toVC.pagingViewController.view.alpha = 1 transitionImageView.removeFromSuperview() UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - toVC.closeButtonBackground.alpha = 1 + toVC.closeButton.alpha = 1 } transitionContext.completeTransition(position == .end) } @@ -140,11 +140,11 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { // update close button UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - fromVC.closeButtonBackground.alpha = 0 + fromVC.closeButton.alpha = 0 } animator.addCompletion { position in UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - fromVC.closeButtonBackground.alpha = position == .end ? 0 : 1 + fromVC.closeButton.alpha = position == .end ? 0 : 1 } } @@ -202,7 +202,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { mediaPreviewTransitionContext.snapshot.contentMode = .scaleAspectFill mediaPreviewTransitionContext.snapshot.clipsToBounds = true transitionMaskView.addSubview(mediaPreviewTransitionContext.snapshot) - fromVC.view.bringSubviewToFront(fromVC.closeButtonBackground) + fromVC.view.bringSubviewToFront(fromVC.closeButton) transitionItem.transitionView = mediaPreviewTransitionContext.transitionView transitionItem.snapshotTransitioning = mediaPreviewTransitionContext.snapshot From 4014fb41f18832bdea1e9d6e314a14919309dda4 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 09:36:57 -0500 Subject: [PATCH 668/733] Allow pinning to a view with padding --- .../Sources/MastodonExtension/UIEdgeInsets.swift | 14 ++++++++++++++ .../Sources/MastodonExtension/UIView.swift | 15 +++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift diff --git a/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift b/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift new file mode 100644 index 000000000..8436ff5d2 --- /dev/null +++ b/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift @@ -0,0 +1,14 @@ +// +// UIEdgeInsets.swift +// +// +// Created by Jed Fox on 2022-11-24. +// + +import UIKit + +extension UIEdgeInsets { + public static func constant(_ offset: CGFloat) -> Self { + UIEdgeInsets(top: offset, left: offset, bottom: offset, right: offset) + } +} diff --git a/MastodonSDK/Sources/MastodonExtension/UIView.swift b/MastodonSDK/Sources/MastodonExtension/UIView.swift index bfa253680..84f87eb20 100644 --- a/MastodonSDK/Sources/MastodonExtension/UIView.swift +++ b/MastodonSDK/Sources/MastodonExtension/UIView.swift @@ -48,20 +48,19 @@ extension UIView { } public extension UIView { - @discardableResult - func pinToParent() -> [NSLayoutConstraint] { - pinTo(to: self.superview) + func pinToParent(padding: UIEdgeInsets = .zero) -> [NSLayoutConstraint] { + pinTo(to: self.superview, padding: padding) } @discardableResult - func pinTo(to view: UIView?) -> [NSLayoutConstraint] { + func pinTo(to view: UIView?, padding: UIEdgeInsets = .zero) -> [NSLayoutConstraint] { guard let pinToView = view else { return [] } let constraints = [ - topAnchor.constraint(equalTo: pinToView.topAnchor), - leadingAnchor.constraint(equalTo: pinToView.leadingAnchor), - trailingAnchor.constraint(equalTo: pinToView.trailingAnchor), - bottomAnchor.constraint(equalTo: pinToView.bottomAnchor), + topAnchor.constraint(equalTo: pinToView.topAnchor, constant: padding.top), + leadingAnchor.constraint(equalTo: pinToView.leadingAnchor, constant: padding.left), + trailingAnchor.constraint(equalTo: pinToView.trailingAnchor, constant: -padding.right), + bottomAnchor.constraint(equalTo: pinToView.bottomAnchor, constant: -padding.bottom), ] NSLayoutConstraint.activate(constraints) return constraints From e8e15f3a0e8252362146b94099dc87ff744a362c Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 09:38:14 -0500 Subject: [PATCH 669/733] Remove support for previewing local images (it was unused) --- .../MediaPreviewImageViewController.swift | 39 +++++++------------ .../Image/MediaPreviewImageViewModel.swift | 11 +----- .../MediaPreviewViewController.swift | 39 +++---------------- .../MediaPreview/MediaPreviewViewModel.swift | 12 +++--- 4 files changed, 28 insertions(+), 73 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 513110d29..68bc0219f 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -68,30 +68,21 @@ extension MediaPreviewImageViewController { let previewImageViewContextMenuInteraction = UIContextMenuInteraction(delegate: self) previewImageView.addInteraction(previewImageViewContextMenuInteraction) - switch viewModel.item { - case .remote(let imageContext): - previewImageView.imageView.accessibilityLabel = imageContext.altText - - if let thumbnail = imageContext.thumbnail { - previewImageView.imageView.image = thumbnail - previewImageView.setup(image: thumbnail, container: self.previewImageView, forceUpdate: true) - } - - previewImageView.imageView.setImage( - url: imageContext.assetURL, - placeholder: imageContext.thumbnail, - scaleToSize: nil - ) { [weak self] image in - guard let self = self else { return } - guard let image = image else { return } - self.previewImageView.setup(image: image, container: self.previewImageView, forceUpdate: true) - } - - case .local(let imageContext): - let image = imageContext.image - previewImageView.imageView.image = image - previewImageView.setup(image: image, container: previewImageView, forceUpdate: true) - + previewImageView.imageView.accessibilityLabel = viewModel.item.altText + + if let thumbnail = viewModel.item.thumbnail { + previewImageView.imageView.image = thumbnail + previewImageView.setup(image: thumbnail, container: self.previewImageView, forceUpdate: true) + } + + previewImageView.imageView.setImage( + url: viewModel.item.assetURL, + placeholder: viewModel.item.thumbnail, + scaleToSize: nil + ) { [weak self] image in + guard let self = self else { return } + guard let image = image else { return } + self.previewImageView.setup(image: image, container: self.previewImageView, forceUpdate: true) } } diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewModel.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewModel.swift index e82118f78..3a4d9edd2 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewModel.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewModel.swift @@ -30,19 +30,10 @@ class MediaPreviewImageViewModel { extension MediaPreviewImageViewModel { - public enum ImagePreviewItem { - case remote(RemoteImageContext) - case local(LocalImageContext) - } - - public struct RemoteImageContext { + public struct ImagePreviewItem { let assetURL: URL? let thumbnail: UIImage? let altText: String? } - - public struct LocalImageContext { - let image: UIImage - } } diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index c25d099a0..e6de7c2e9 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -241,19 +241,8 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { ) { switch action { case .savePhoto: - let _savePublisher: AnyPublisher? = { - switch viewController.viewModel.item { - case .remote(let previewContext): - guard let assetURL = previewContext.assetURL else { return nil } - return context.photoLibraryService.save(imageSource: .url(assetURL)) - case .local(let previewContext): - return context.photoLibraryService.save(imageSource: .image(previewContext.image)) - } - }() - guard let savePublisher = _savePublisher else { - return - } - savePublisher + guard let assetURL = viewController.viewModel.item.assetURL else { return } + context.photoLibraryService.save(imageSource: .url(assetURL)) .sink { [weak self] completion in guard let self = self else { return } switch completion { @@ -277,20 +266,9 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { } .store(in: &context.disposeBag) case .copyPhoto: - let _copyPublisher: AnyPublisher? = { - switch viewController.viewModel.item { - case .remote(let previewContext): - guard let assetURL = previewContext.assetURL else { return nil } - return context.photoLibraryService.copy(imageSource: .url(assetURL)) - case .local(let previewContext): - return context.photoLibraryService.copy(imageSource: .image(previewContext.image)) - } - }() - guard let copyPublisher = _copyPublisher else { - return - } + guard let assetURL = viewController.viewModel.item.assetURL else { return } - copyPublisher + context.photoLibraryService.copy(imageSource: .url(assetURL)) .sink { completion in switch completion { case .failure(let error): @@ -309,13 +287,8 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { let activityViewController = UIActivityViewController( activityItems: { var activityItems: [Any] = [] - switch viewController.viewModel.item { - case .remote(let previewContext): - if let assetURL = previewContext.assetURL { - activityItems.append(assetURL) - } - case .local(let previewContext): - activityItems.append(previewContext.image) + if let assetURL = viewController.viewModel.item.assetURL { + activityItems.append(assetURL) } return activityItems }(), diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift index 3f60b19e5..3d6c4c14d 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift @@ -51,11 +51,11 @@ final class MediaPreviewViewModel: NSObject { let viewController = MediaPreviewImageViewController() let viewModel = MediaPreviewImageViewModel( context: context, - item: .remote(.init( + item: .init( assetURL: attachment.assetURL.flatMap { URL(string: $0) }, thumbnail: previewContext.thumbnail(at: i), altText: attachment.altDescription - )) + ) ) viewController.viewModel = viewModel viewControllers.append(viewController) @@ -87,11 +87,11 @@ final class MediaPreviewViewModel: NSObject { let viewController = MediaPreviewImageViewController() let viewModel = MediaPreviewImageViewModel( context: context, - item: .remote(.init( + item: .init( assetURL: previewContext.assetURL.flatMap { URL(string: $0) }, thumbnail: previewContext.thumbnail, altText: nil - )) + ) ) viewController.viewModel = viewModel viewControllers.append(viewController) @@ -99,11 +99,11 @@ final class MediaPreviewViewModel: NSObject { let viewController = MediaPreviewImageViewController() let viewModel = MediaPreviewImageViewModel( context: context, - item: .remote(.init( + item: .init( assetURL: previewContext.assetURL.flatMap { URL(string: $0) }, thumbnail: previewContext.thumbnail, altText: nil - )) + ) ) viewController.viewModel = viewModel viewControllers.append(viewController) From 582d1cf295bda717b7bc3a71990c7cf3a74b5d28 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 09:39:24 -0500 Subject: [PATCH 670/733] Add an ALT button to the media preview to display alt text --- Mastodon.xcodeproj/project.pbxproj | 4 ++ .../MediaPreview/AltViewController.swift | 72 +++++++++++++++++++ Mastodon/Scene/MediaPreview/HUDButton.swift | 7 ++ .../MediaPreviewImageViewController.swift | 4 ++ .../MediaPreviewViewController.swift | 22 +++++- .../MediaPreview/MediaPreviewViewModel.swift | 11 +-- .../MediaPreviewVideoViewController.swift | 4 ++ .../Video/MediaPreviewVideoViewModel.swift | 9 +++ 8 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 Mastodon/Scene/MediaPreview/AltViewController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index aca99ccfb..afb0c30ab 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; 85BC11B1292FF92C00E191CD /* HUDButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B0292FF92C00E191CD /* HUDButton.swift */; }; + 85BC11B32932414900E191CD /* AltViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltViewController.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; @@ -622,6 +623,7 @@ 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; 85BC11B0292FF92C00E191CD /* HUDButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDButton.swift; sourceTree = ""; }; + 85BC11B22932414900E191CD /* AltViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltViewController.swift; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = ""; }; 8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = ""; }; @@ -1978,6 +1980,7 @@ DB6180E1263919780018D199 /* Paging */, 85BC11B0292FF92C00E191CD /* HUDButton.swift */, DB6180DC263918E30018D199 /* MediaPreviewViewController.swift */, + 85BC11B22932414900E191CD /* AltViewController.swift */, DB6180F926391F2E0018D199 /* MediaPreviewViewModel.swift */, ); path = MediaPreview; @@ -3539,6 +3542,7 @@ DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */, 2D4AD8A226316CD200613EFC /* SelectedAccountSection.swift in Sources */, DB3EA8F1281B9EF600598866 /* DiscoveryCommunityViewModel+Diffable.swift in Sources */, + 85BC11B32932414900E191CD /* AltViewController.swift in Sources */, DB63F775279A997D00455B82 /* NotificationTableViewCell+ViewModel.swift in Sources */, DB98EB5927B109890082E365 /* ReportSupplementaryViewController.swift in Sources */, DB0617EB277EF3820030EE79 /* GradientBorderView.swift in Sources */, diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift new file mode 100644 index 000000000..f15f1d84d --- /dev/null +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -0,0 +1,72 @@ +// +// AltViewController.swift +// Mastodon +// +// Created by Jed Fox on 2022-11-26. +// + +import SwiftUI + +class AltViewController: UIViewController { + var alt: String? + let label = UILabel() + + convenience init(alt: String?, sourceView: UIView?) { + self.init(nibName: nil, bundle: nil) + self.alt = alt + self.modalPresentationStyle = .popover + self.popoverPresentationController?.delegate = self + self.popoverPresentationController?.permittedArrowDirections = .up + self.popoverPresentationController?.sourceView = sourceView + self.overrideUserInterfaceStyle = .dark + } + + @objc override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + } + + @MainActor required dynamic init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + label.translatesAutoresizingMaskIntoConstraints = false + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.lineBreakStrategy = .standard + label.font = .preferredFont(forTextStyle: .callout) + label.text = alt ?? "ummmmmmm tbd but you shouldn’t see this" + + view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(label) + + NSLayoutConstraint.activate( + NSLayoutConstraint.constraints(withVisualFormat: "V:|-[label]-|", metrics: nil, views: ["label": label]) + ) + NSLayoutConstraint.activate( + NSLayoutConstraint.constraints(withVisualFormat: "H:|-[label]-|", metrics: nil, views: ["label": label]) + ) + NSLayoutConstraint.activate([ + label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), + ]) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + UIView.performWithoutAnimation { + preferredContentSize = CGSize( + width: label.intrinsicContentSize.width + view.layoutMargins.left + view.layoutMargins.right, + height: label.intrinsicContentSize.height + view.layoutMargins.top + view.layoutMargins.bottom + ) + } + } +} + +// MARK: UIPopoverPresentationControllerDelegate +extension AltViewController: UIPopoverPresentationControllerDelegate { + func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { + .none + } +} diff --git a/Mastodon/Scene/MediaPreview/HUDButton.swift b/Mastodon/Scene/MediaPreview/HUDButton.swift index b08f95eb4..0089ebcb1 100644 --- a/Mastodon/Scene/MediaPreview/HUDButton.swift +++ b/Mastodon/Scene/MediaPreview/HUDButton.swift @@ -25,7 +25,9 @@ class HUDButton: UIView { let button: UIButton = { let button = HighlightDimmableButton() button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) + button.contentEdgeInsets = .constant(7) button.imageView?.tintColor = .label + button.titleLabel?.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)) return button }() @@ -56,4 +58,9 @@ class HUDButton: UIView { heightAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), ]) } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)) + } } diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 68bc0219f..c87788aa1 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -110,6 +110,10 @@ extension MediaPreviewImageViewController: MediaPreviewPage { } } } + + var altText: String? { + viewModel.item.altText + } } // MARK: - ImageAnalysisInteractionDelegate diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index e6de7c2e9..3c9821eb6 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -29,6 +29,10 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency { button.setImage(UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 16, weight: .bold))!, for: .normal) } + let altButton = HUDButton { button in + button.setTitle("ALT", for: .normal) + } + deinit { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) } @@ -58,7 +62,13 @@ extension MediaPreviewViewController { closeButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor), closeButton.widthAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), ]) - + + view.addSubview(altButton) + NSLayoutConstraint.activate([ + altButton.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), + altButton.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor), + ]) + viewModel.mediaPreviewImageViewControllerDelegate = self pagingViewController.interPageSpacing = 10 @@ -66,7 +76,8 @@ extension MediaPreviewViewController { pagingViewController.dataSource = viewModel closeButton.button.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside) - + altButton.button.addTarget(self, action: #selector(MediaPreviewViewController.altButtonPressed(_:)), for: .touchUpInside) + // bind view model viewModel.$currentPage .receive(on: DispatchQueue.main) @@ -144,7 +155,12 @@ extension MediaPreviewViewController { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) dismiss(animated: true, completion: nil) } - + + @objc private func altButtonPressed(_ sender: UIButton) { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + present(AltViewController(alt: viewModel.viewControllers[viewModel.currentPage].altText, sourceView: sender), animated: true) + } + } // MARK: - MediaPreviewingViewController diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift index 3d6c4c14d..7cdee02fe 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift @@ -14,6 +14,7 @@ import MastodonCore protocol MediaPreviewPage: UIViewController { func setShowingChrome(_ showingChrome: Bool) + var altText: String? { get } } final class MediaPreviewViewModel: NSObject { @@ -27,9 +28,9 @@ final class MediaPreviewViewModel: NSObject { @Published var currentPage: Int @Published var showingChrome = true - + // output - let viewControllers: [UIViewController] + let viewControllers: [MediaPreviewPage] private var disposeBag: Set = [] @@ -65,7 +66,8 @@ final class MediaPreviewViewModel: NSObject { context: context, item: .gif(.init( assetURL: attachment.assetURL.flatMap { URL(string: $0) }, - previewURL: attachment.previewURL.flatMap { URL(string: $0) } + previewURL: attachment.previewURL.flatMap { URL(string: $0) }, + altText: attachment.altDescription )) ) viewController.viewModel = viewModel @@ -76,7 +78,8 @@ final class MediaPreviewViewModel: NSObject { context: context, item: .video(.init( assetURL: attachment.assetURL.flatMap { URL(string: $0) }, - previewURL: attachment.previewURL.flatMap { URL(string: $0) } + previewURL: attachment.previewURL.flatMap { URL(string: $0) }, + altText: attachment.altDescription )) ) viewController.viewModel = viewModel diff --git a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift index e924f38d4..b91705cc5 100644 --- a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift +++ b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift @@ -111,6 +111,10 @@ extension MediaPreviewVideoViewController: MediaPreviewPage { func setShowingChrome(_ showingChrome: Bool) { // TODO: does this do anything? } + + var altText: String? { + viewModel.item.altText + } } // MARK: - AVPlayerViewControllerDelegate diff --git a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift index 97e5f955b..9cc9666dd 100644 --- a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift +++ b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift @@ -125,17 +125,26 @@ extension MediaPreviewVideoViewModel { case .gif(let mediaContext): return mediaContext.assetURL } } + + var altText: String? { + switch self { + case .video(let mediaContext): return mediaContext.altText + case .gif(let mediaContext): return mediaContext.altText + } + } } struct RemoteVideoContext { let assetURL: URL? let previewURL: URL? + let altText: String? // let thumbnail: UIImage? } struct RemoteGIFContext { let assetURL: URL? let previewURL: URL? + let altText: String? } } From ed580541f0597c82e80d453c05522f440531c724 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 14:29:30 -0500 Subject: [PATCH 671/733] Merge top buttons into a single parent view (also fix tapping just outside a HUDButton) --- Mastodon/Scene/MediaPreview/HUDButton.swift | 8 ++++ .../MediaPreviewViewController.swift | 46 +++++++++++++++---- ...wViewControllerAnimatedTransitioning.swift | 14 +++--- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/HUDButton.swift b/Mastodon/Scene/MediaPreview/HUDButton.swift index 0089ebcb1..e82fba0f6 100644 --- a/Mastodon/Scene/MediaPreview/HUDButton.swift +++ b/Mastodon/Scene/MediaPreview/HUDButton.swift @@ -63,4 +63,12 @@ class HUDButton: UIView { super.traitCollectionDidChange(previousTraitCollection) button.titleLabel?.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)) } + + override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + button.point(inside: button.convert(point, from: self), with: event) + } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + button + } } diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index 3c9821eb6..eaf740a2b 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -24,7 +24,32 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency { let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) let pagingViewController = MediaPreviewPagingViewController() - + + let topToolbar: UIStackView = { + class TouchTransparentStackView: UIStackView { + // allow button hit boxes to grow outside of this view’s bounds + override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + subviews.contains { $0.point(inside: $0.convert(point, from: self), with: event) } + } + + // allow taps on blank areas to pass through + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let view = super.hitTest(point, with: event) + if view == self { + return nil + } + return view + } + } + + let stackView = TouchTransparentStackView() + stackView.axis = .horizontal + stackView.distribution = .equalSpacing + stackView.alignment = .fill + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + let closeButton = HUDButton { button in button.setImage(UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 16, weight: .bold))!, for: .normal) } @@ -56,18 +81,19 @@ extension MediaPreviewViewController { visualEffectView.pinTo(to: pagingViewController.view) pagingViewController.didMove(toParent: self) - view.addSubview(closeButton) + view.addSubview(topToolbar) + NSLayoutConstraint.activate([ + topToolbar.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), + topToolbar.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor), + topToolbar.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor), + ]) + + topToolbar.addArrangedSubview(closeButton) NSLayoutConstraint.activate([ - closeButton.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), - closeButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor), closeButton.widthAnchor.constraint(equalToConstant: HUDButton.height).priority(.defaultHigh), ]) - view.addSubview(altButton) - NSLayoutConstraint.activate([ - altButton.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 12), - altButton.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor), - ]) + topToolbar.addArrangedSubview(altButton) viewModel.mediaPreviewImageViewControllerDelegate = self @@ -121,7 +147,7 @@ extension MediaPreviewViewController { .sink { [weak self] showingChrome in UIView.animate(withDuration: 0.3) { self?.setNeedsStatusBarAppearanceUpdate() - self?.closeButton.alpha = showingChrome ? 1 : 0 + self?.topToolbar.alpha = showingChrome ? 1 : 0 } } .store(in: &disposeBag) diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index 7bf81f0b0..44cb68428 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -81,8 +81,8 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { transitionItem.transitionView = transitionImageView transitionContext.containerView.addSubview(transitionImageView) - toVC.closeButton.alpha = 0 - + toVC.topToolbar.alpha = 0 + if UIAccessibility.isReduceTransparencyEnabled { toVC.visualEffectView.alpha = 0 } @@ -101,7 +101,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { toVC.pagingViewController.view.alpha = 1 transitionImageView.removeFromSuperview() UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - toVC.closeButton.alpha = 1 + toVC.topToolbar.alpha = 1 } transitionContext.completeTransition(position == .end) } @@ -138,13 +138,13 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { } } - // update close button + // update top toolbar UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - fromVC.closeButton.alpha = 0 + fromVC.topToolbar.alpha = 0 } animator.addCompletion { position in UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { - fromVC.closeButton.alpha = position == .end ? 0 : 1 + fromVC.topToolbar.alpha = position == .end ? 0 : 1 } } @@ -202,7 +202,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { mediaPreviewTransitionContext.snapshot.contentMode = .scaleAspectFill mediaPreviewTransitionContext.snapshot.clipsToBounds = true transitionMaskView.addSubview(mediaPreviewTransitionContext.snapshot) - fromVC.view.bringSubviewToFront(fromVC.closeButton) + fromVC.view.bringSubviewToFront(fromVC.topToolbar) transitionItem.transitionView = mediaPreviewTransitionContext.transitionView transitionItem.snapshotTransitioning = mediaPreviewTransitionContext.snapshot From 501e17bf18089d074135217528bc117762c8a6c6 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 15:11:13 -0500 Subject: [PATCH 672/733] Hide the ALT button when alt text is unavailable --- .../Scene/MediaPreview/AltViewController.swift | 12 ++++-------- .../Image/MediaPreviewImageViewController.swift | 4 ---- .../MediaPreviewViewController.swift | 17 ++++++++++++++++- .../MediaPreview/MediaPreviewViewModel.swift | 9 ++++++++- .../Video/MediaPreviewVideoViewController.swift | 4 ---- .../Video/MediaPreviewVideoViewModel.swift | 7 ------- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index f15f1d84d..318514ae3 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -8,12 +8,12 @@ import SwiftUI class AltViewController: UIViewController { - var alt: String? + private var alt: String let label = UILabel() - convenience init(alt: String?, sourceView: UIView?) { - self.init(nibName: nil, bundle: nil) + init(alt: String, sourceView: UIView?) { self.alt = alt + super.init(nibName: nil, bundle: nil) self.modalPresentationStyle = .popover self.popoverPresentationController?.delegate = self self.popoverPresentationController?.permittedArrowDirections = .up @@ -21,10 +21,6 @@ class AltViewController: UIViewController { self.overrideUserInterfaceStyle = .dark } - @objc override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { - super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) - } - @MainActor required dynamic init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -37,7 +33,7 @@ class AltViewController: UIViewController { label.lineBreakMode = .byWordWrapping label.lineBreakStrategy = .standard label.font = .preferredFont(forTextStyle: .callout) - label.text = alt ?? "ummmmmmm tbd but you shouldn’t see this" + label.text = alt view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(label) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index c87788aa1..68bc0219f 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -110,10 +110,6 @@ extension MediaPreviewImageViewController: MediaPreviewPage { } } } - - var altText: String? { - viewModel.item.altText - } } // MARK: - ImageAnalysisInteractionDelegate diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index eaf740a2b..d4a415f5f 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -141,6 +141,20 @@ extension MediaPreviewViewController { } .store(in: &disposeBag) + viewModel.$altText + .receive(on: DispatchQueue.main) + .sink { [weak self] altText in + guard let self else { return } + UIView.animate(withDuration: 0.3) { + if altText == nil { + self.altButton.alpha = 0 + } else { + self.altButton.alpha = 1 + } + } + } + .store(in: &disposeBag) + viewModel.$showingChrome .receive(on: DispatchQueue.main) .removeDuplicates() @@ -184,7 +198,8 @@ extension MediaPreviewViewController { @objc private func altButtonPressed(_ sender: UIButton) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - present(AltViewController(alt: viewModel.viewControllers[viewModel.currentPage].altText, sourceView: sender), animated: true) + guard let alt = viewModel.altText else { return } + present(AltViewController(alt: alt, sourceView: sender), animated: true) } } diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift index 7cdee02fe..a6b604d6f 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewModel.swift @@ -14,7 +14,6 @@ import MastodonCore protocol MediaPreviewPage: UIViewController { func setShowingChrome(_ showingChrome: Bool) - var altText: String? { get } } final class MediaPreviewViewModel: NSObject { @@ -28,6 +27,7 @@ final class MediaPreviewViewModel: NSObject { @Published var currentPage: Int @Published var showingChrome = true + @Published var altText: String? // output let viewControllers: [MediaPreviewPage] @@ -43,8 +43,11 @@ final class MediaPreviewViewModel: NSObject { self.item = item var currentPage = 0 var viewControllers: [MediaPreviewPage] = [] + var getAltText = { (page: Int) -> String? in nil } switch item { case .attachment(let previewContext): + getAltText = { previewContext.attachments[$0].altDescription } + currentPage = previewContext.initialIndex for (i, attachment) in previewContext.attachments.enumerated() { switch attachment.kind { @@ -117,6 +120,10 @@ final class MediaPreviewViewModel: NSObject { self.transitionItem = transitionItem super.init() + self.$currentPage + .map(getAltText) + .assign(to: &$altText) + for viewController in viewControllers { self.$showingChrome .sink { [weak viewController] showingChrome in diff --git a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift index b91705cc5..e924f38d4 100644 --- a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift +++ b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewController.swift @@ -111,10 +111,6 @@ extension MediaPreviewVideoViewController: MediaPreviewPage { func setShowingChrome(_ showingChrome: Bool) { // TODO: does this do anything? } - - var altText: String? { - viewModel.item.altText - } } // MARK: - AVPlayerViewControllerDelegate diff --git a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift index 9cc9666dd..a6542d464 100644 --- a/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift +++ b/Mastodon/Scene/MediaPreview/Video/MediaPreviewVideoViewModel.swift @@ -125,13 +125,6 @@ extension MediaPreviewVideoViewModel { case .gif(let mediaContext): return mediaContext.assetURL } } - - var altText: String? { - switch self { - case .video(let mediaContext): return mediaContext.altText - case .gif(let mediaContext): return mediaContext.altText - } - } } struct RemoteVideoContext { From 754b0a7eb073740799b7c878925fd4f56e7036f8 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 15:14:43 -0500 Subject: [PATCH 673/733] Move HUDButton to MastodonUI --- Mastodon.xcodeproj/project.pbxproj | 4 ---- .../MastodonUI/View/Button}/HUDButton.swift | 15 +++++++-------- 2 files changed, 7 insertions(+), 12 deletions(-) rename {Mastodon/Scene/MediaPreview => MastodonSDK/Sources/MastodonUI/View/Button}/HUDButton.swift (82%) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index afb0c30ab..0ee9fa7e8 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -98,7 +98,6 @@ 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; }; 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; - 85BC11B1292FF92C00E191CD /* HUDButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B0292FF92C00E191CD /* HUDButton.swift */; }; 85BC11B32932414900E191CD /* AltViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltViewController.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; @@ -622,7 +621,6 @@ 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; - 85BC11B0292FF92C00E191CD /* HUDButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HUDButton.swift; sourceTree = ""; }; 85BC11B22932414900E191CD /* AltViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltViewController.swift; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = ""; }; @@ -1978,7 +1976,6 @@ DBB45B5727B39FCC002DC5A7 /* Video */, DB6180F026391CAB0018D199 /* Image */, DB6180E1263919780018D199 /* Paging */, - 85BC11B0292FF92C00E191CD /* HUDButton.swift */, DB6180DC263918E30018D199 /* MediaPreviewViewController.swift */, 85BC11B22932414900E191CD /* AltViewController.swift */, DB6180F926391F2E0018D199 /* MediaPreviewViewModel.swift */, @@ -3425,7 +3422,6 @@ 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */, 2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */, DB852D1C26FB021500FC9D81 /* RootSplitViewController.swift in Sources */, - 85BC11B1292FF92C00E191CD /* HUDButton.swift in Sources */, DB697DD1278F4871004EF2F7 /* AutoGenerateTableViewDelegate.swift in Sources */, DB02CDBF2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift in Sources */, DB3E6FFA2807C47900B035AE /* DiscoveryForYouViewModel+Diffable.swift in Sources */, diff --git a/Mastodon/Scene/MediaPreview/HUDButton.swift b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift similarity index 82% rename from Mastodon/Scene/MediaPreview/HUDButton.swift rename to MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift index e82fba0f6..78579bb1e 100644 --- a/Mastodon/Scene/MediaPreview/HUDButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift @@ -6,11 +6,10 @@ // import UIKit -import MastodonUI -class HUDButton: UIView { +public class HUDButton: UIView { - static let height: CGFloat = 30 + public static let height: CGFloat = 30 let background: UIVisualEffectView = { let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)) @@ -22,7 +21,7 @@ class HUDButton: UIView { let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemUltraThinMaterial))) - let button: UIButton = { + public let button: UIButton = { let button = HighlightDimmableButton() button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) button.contentEdgeInsets = .constant(7) @@ -31,7 +30,7 @@ class HUDButton: UIView { return button }() - init(configure: (UIButton) -> Void) { + public init(configure: (UIButton) -> Void) { super.init(frame: .zero) configure(button) @@ -59,16 +58,16 @@ class HUDButton: UIView { ]) } - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) button.titleLabel?.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)) } - override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { button.point(inside: button.convert(point, from: self), with: event) } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { button } } From 7ab6ea0d2344f8b8be9c10b52e43d17f6a34dd09 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 15:53:09 -0500 Subject: [PATCH 674/733] Make alt text selectable --- .../MediaPreview/AltViewController.swift | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 318514ae3..b8f486890 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -9,7 +9,7 @@ import SwiftUI class AltViewController: UIViewController { private var alt: String - let label = UILabel() + let label = UITextView() init(alt: String, sourceView: UIView?) { self.alt = alt @@ -29,10 +29,20 @@ class AltViewController: UIViewController { super.viewDidLoad() label.translatesAutoresizingMaskIntoConstraints = false - label.numberOfLines = 0 - label.lineBreakMode = .byWordWrapping - label.lineBreakStrategy = .standard + label.textContainer.maximumNumberOfLines = 0 + label.textContainer.lineBreakMode = .byWordWrapping + label.textContainerInset = UIEdgeInsets( + top: 8, + left: 0, + bottom: -label.textContainer.lineFragmentPadding, + right: 0 + ) label.font = .preferredFont(forTextStyle: .callout) + label.isScrollEnabled = false + label.backgroundColor = .clear + label.isOpaque = false + label.isEditable = false + label.tintColor = .white label.text = alt view.translatesAutoresizingMaskIntoConstraints = false @@ -42,7 +52,7 @@ class AltViewController: UIViewController { NSLayoutConstraint.constraints(withVisualFormat: "V:|-[label]-|", metrics: nil, views: ["label": label]) ) NSLayoutConstraint.activate( - NSLayoutConstraint.constraints(withVisualFormat: "H:|-[label]-|", metrics: nil, views: ["label": label]) + NSLayoutConstraint.constraints(withVisualFormat: "H:|-(8)-[label]-(8)-|", metrics: nil, views: ["label": label]) ) NSLayoutConstraint.activate([ label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), From dbf95f726c1eceb728dc52e6051342e050244042 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 26 Nov 2022 16:37:48 -0500 Subject: [PATCH 675/733] fix preferredContentSize --- Mastodon/Scene/MediaPreview/AltViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index b8f486890..305487397 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -63,7 +63,7 @@ class AltViewController: UIViewController { super.viewDidLayoutSubviews() UIView.performWithoutAnimation { preferredContentSize = CGSize( - width: label.intrinsicContentSize.width + view.layoutMargins.left + view.layoutMargins.right, + width: label.intrinsicContentSize.width + 16, height: label.intrinsicContentSize.height + view.layoutMargins.top + view.layoutMargins.bottom ) } From 31bd74383dfd6e3e6335943861252887f14abeae Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Tue, 20 Dec 2022 11:49:55 -0600 Subject: [PATCH 676/733] Move MastodonSDK to dynamic framework --- Mastodon.xcodeproj/project.pbxproj | 34 ++++++++++++++++-------------- MastodonSDK/Package.swift | 4 +++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 74b7841a5..50114c55b 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -75,6 +75,11 @@ 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */; }; 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; }; 2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */; }; + 357FEE8729522CA50021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8629522CA50021C9DC /* MastodonSDK */; }; + 357FEE8829522CA50021C9DC /* MastodonSDK in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8629522CA50021C9DC /* MastodonSDK */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 357FEE8A29522CB60021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8929522CB60021C9DC /* MastodonSDK */; }; + 357FEE8E29522CC00021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8D29522CC00021C9DC /* MastodonSDK */; }; + 357FEE9229522CE60021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE9129522CE60021C9DC /* MastodonSDK */; }; 5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */; }; 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */; }; 5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B90C456262599800002E742 /* SettingsViewModel.swift */; }; @@ -169,10 +174,6 @@ DB1FD44425F26CCC004CFCFC /* PickServerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */; }; DB1FD45025F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD44F25F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift */; }; DB1FD45A25F27898004CFCFC /* CategoryPickerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */; }; - DB22C92228E700A10082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92128E700A10082A9E9 /* MastodonSDK */; }; - DB22C92428E700A80082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92328E700A80082A9E9 /* MastodonSDK */; }; - DB22C92628E700AF0082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92528E700AF0082A9E9 /* MastodonSDK */; }; - DB22C92828E700B70082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92728E700B70082A9E9 /* MastodonSDK */; }; DB2B3ABC25E37E15007045F9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB2B3ABE25E37E15007045F9 /* InfoPlist.strings */; }; DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; }; DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; }; @@ -492,6 +493,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 357FEE8829522CA50021C9DC /* MastodonSDK in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -1085,7 +1087,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB22C92428E700A80082A9E9 /* MastodonSDK in Frameworks */, + 357FEE8729522CA50021C9DC /* MastodonSDK in Frameworks */, DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */, 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */, ); @@ -1112,7 +1114,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB22C92828E700B70082A9E9 /* MastodonSDK in Frameworks */, + 357FEE9229522CE60021C9DC /* MastodonSDK in Frameworks */, DB8FABC726AEC7B2008E5AF4 /* Intents.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1121,7 +1123,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB22C92628E700AF0082A9E9 /* MastodonSDK in Frameworks */, + 357FEE8E29522CC00021C9DC /* MastodonSDK in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1129,7 +1131,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB22C92228E700A10082A9E9 /* MastodonSDK in Frameworks */, + 357FEE8A29522CB60021C9DC /* MastodonSDK in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2755,7 +2757,7 @@ ); name = Mastodon; packageProductDependencies = ( - DB22C92328E700A80082A9E9 /* MastodonSDK */, + 357FEE8629522CA50021C9DC /* MastodonSDK */, ); productName = Mastodon; productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */; @@ -2814,7 +2816,7 @@ ); name = MastodonIntent; packageProductDependencies = ( - DB22C92728E700B70082A9E9 /* MastodonSDK */, + 357FEE9129522CE60021C9DC /* MastodonSDK */, ); productName = MastodonIntent; productReference = DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */; @@ -2834,7 +2836,7 @@ ); name = ShareActionExtension; packageProductDependencies = ( - DB22C92528E700AF0082A9E9 /* MastodonSDK */, + 357FEE8D29522CC00021C9DC /* MastodonSDK */, ); productName = ShareActionExtension; productReference = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */; @@ -2854,7 +2856,7 @@ ); name = NotificationService; packageProductDependencies = ( - DB22C92128E700A10082A9E9 /* MastodonSDK */, + 357FEE8929522CB60021C9DC /* MastodonSDK */, ); productName = NotificationService; productReference = DBF8AE13263293E400C9C23C /* NotificationService.appex */; @@ -4642,19 +4644,19 @@ /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ - DB22C92128E700A10082A9E9 /* MastodonSDK */ = { + 357FEE8629522CA50021C9DC /* MastodonSDK */ = { isa = XCSwiftPackageProductDependency; productName = MastodonSDK; }; - DB22C92328E700A80082A9E9 /* MastodonSDK */ = { + 357FEE8929522CB60021C9DC /* MastodonSDK */ = { isa = XCSwiftPackageProductDependency; productName = MastodonSDK; }; - DB22C92528E700AF0082A9E9 /* MastodonSDK */ = { + 357FEE8D29522CC00021C9DC /* MastodonSDK */ = { isa = XCSwiftPackageProductDependency; productName = MastodonSDK; }; - DB22C92728E700B70082A9E9 /* MastodonSDK */ = { + 357FEE9129522CE60021C9DC /* MastodonSDK */ = { isa = XCSwiftPackageProductDependency; productName = MastodonSDK; }; diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 1ac22e6a7..7939f051e 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -12,6 +12,7 @@ let package = Package( products: [ .library( name: "MastodonSDK", + type: .dynamic, targets: [ "CoreDataStack", "MastodonAsset", @@ -21,7 +22,8 @@ let package = Package( "MastodonLocalization", "MastodonSDK", "MastodonUI", - ]) + ] + ) ], dependencies: [ .package(name: "ArkanaKeys", path: "../dependencies/ArkanaKeys"), From 26aff2d627a71c686fed1ae29ab46426182d9f2c Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 10:09:18 -0500 Subject: [PATCH 677/733] MediaView: remove unused property --- MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 54560a8ce..fd2d10872 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -16,12 +16,6 @@ public final class MediaView: UIView { var _disposeBag = Set() public static let cornerRadius: CGFloat = 0 - public static let durationFormatter: DateComponentsFormatter = { - let formatter = DateComponentsFormatter() - formatter.zeroFormattingBehavior = .pad - formatter.allowedUnits = [.minute, .second] - return formatter - }() public static let placeholderImage = UIImage.placeholder(color: .systemGray6) public let container = TouchBlockingView() From c9a74055198b0a8aff76abf62678456c41cf14f1 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 11:03:57 -0500 Subject: [PATCH 678/733] Add altDescription attribute to MediaView.Configuration values --- .../Extension/CGSize+Hashable.swift | 15 +++++++++++ .../Content/MediaView+Configuration.swift | 26 +++++++------------ .../MastodonUI/View/Content/MediaView.swift | 3 ++- .../View/Content/NewsView+Configuration.swift | 3 ++- 4 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/Extension/CGSize+Hashable.swift diff --git a/MastodonSDK/Sources/MastodonUI/Extension/CGSize+Hashable.swift b/MastodonSDK/Sources/MastodonUI/Extension/CGSize+Hashable.swift new file mode 100644 index 000000000..0578d543e --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Extension/CGSize+Hashable.swift @@ -0,0 +1,15 @@ +// +// CGSize.swift +// +// +// Created by Jed Fox on 2022-12-20. +// + +import Foundation + +extension CGSize: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine(width) + hasher.combine(height) + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift index 438baff7e..1da4e5392 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift @@ -101,19 +101,16 @@ extension MediaView.Configuration { public struct ImageInfo: Hashable { public let aspectRadio: CGSize public let assetURL: String? + public let altDescription: String? public init( aspectRadio: CGSize, - assetURL: String? + assetURL: String?, + altDescription: String? ) { self.aspectRadio = aspectRadio self.assetURL = assetURL - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(aspectRadio.width) - hasher.combine(aspectRadio.height) - assetURL.flatMap { hasher.combine($0) } + self.altDescription = altDescription } } @@ -121,26 +118,21 @@ extension MediaView.Configuration { public let aspectRadio: CGSize public let assetURL: String? public let previewURL: String? + public let altDescription: String? public let durationMS: Int? public init( aspectRadio: CGSize, assetURL: String?, previewURL: String?, + altDescription: String?, durationMS: Int? ) { self.aspectRadio = aspectRadio self.assetURL = assetURL self.previewURL = previewURL self.durationMS = durationMS - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(aspectRadio.width) - hasher.combine(aspectRadio.height) - assetURL.flatMap { hasher.combine($0) } - previewURL.flatMap { hasher.combine($0) } - durationMS.flatMap { hasher.combine($0) } + self.altDescription = altDescription } } @@ -187,6 +179,7 @@ extension MediaView { aspectRadio: attachment.size, assetURL: attachment.assetURL, previewURL: attachment.previewURL, + altDescription: attachment.altDescription, durationMS: attachment.durationMS ) } @@ -199,7 +192,8 @@ extension MediaView { case .image: let info = MediaView.Configuration.ImageInfo( aspectRadio: attachment.size, - assetURL: attachment.assetURL + assetURL: attachment.assetURL, + altDescription: attachment.altDescription ) return .init( info: .image(info: info), diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index fd2d10872..2e1a751c0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -189,7 +189,8 @@ extension MediaView { private func bindVideo(configuration: Configuration, info: Configuration.VideoInfo) { let imageInfo = Configuration.ImageInfo( aspectRadio: info.aspectRadio, - assetURL: info.previewURL + assetURL: info.previewURL, + altDescription: info.altDescription ) bindImage(configuration: configuration, info: imageInfo) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift index 7f44232aa..560721b74 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift @@ -39,7 +39,8 @@ extension NewsView { let configuration = MediaView.Configuration( info: .image(info: .init( aspectRadio: CGSize(width: link.width, height: link.height), - assetURL: link.image + assetURL: link.image, + altDescription: nil )), blurhash: link.blurhash ) From 28b52533f9039b774a571c9fe70e05a9202a96d7 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 11:45:20 -0500 Subject: [PATCH 679/733] =?UTF-8?q?Add=20a=20non-functional=20=E2=80=9CALT?= =?UTF-8?q?=E2=80=9D=20button=20to=20MediaView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Content/MediaAltTextOverlay.swift | 62 +++++++++++++++++++ .../MastodonUI/View/Content/MediaView.swift | 36 +++++++++++ 2 files changed, 98 insertions(+) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift new file mode 100644 index 000000000..91aeb8993 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -0,0 +1,62 @@ +// +// MediaAltTextOverlay.swift +// +// +// Created by Jed Fox on 2022-12-20. +// + +import SwiftUI + +@available(iOS 15.0, *) +struct MediaAltTextOverlay: View { + var altDescription: String? + + @State private var showingAlt = false + + var body: some View { + HStack { + VStack { + Spacer(minLength: 0) + if altDescription != nil { + Button("ALT") {} + .buttonStyle(AltButtonStyle()) + } + } + Spacer(minLength: 0) + } + .padding(.horizontal, 16) + .padding(.vertical, 8) + .onChange(of: altDescription) { _ in + showingAlt = false + } + } +} + +@available(iOS 15.0, *) +private struct AltButtonStyle: ButtonStyle { + @Environment(\.pixelLength) private var pixelLength + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(.caption.weight(.semibold)) + .foregroundColor(.white) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.black.opacity(0.85)) + .cornerRadius(4) + .opacity(configuration.isPressed ? 0.5 : 1) + .overlay( + .white.opacity(0.4), + in: RoundedRectangle(cornerRadius: 4) + .inset(by: -0.5) + .stroke(lineWidth: 0.5) + ) + } +} + +@available(iOS 15.0, *) +struct MediaAltTextOverlay_Previews: PreviewProvider { + static var previews: some View { + MediaAltTextOverlay(altDescription: nil) + MediaAltTextOverlay(altDescription: "Hello, world!") + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 2e1a751c0..8ce96674e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -10,6 +10,7 @@ import AVKit import UIKit import Combine import AlamofireImage +import SwiftUI public final class MediaView: UIView { @@ -71,6 +72,20 @@ public final class MediaView: UIView { return label }() + let _altViewController: UIViewController! = { + if #available(iOS 15.0, *) { + let vc = UIHostingController(rootView: MediaAltTextOverlay()) + vc.view.backgroundColor = .clear + return vc + } else { + return nil + } + }() + @available(iOS 15.0, *) + var altViewController: UIHostingController { + _altViewController as! UIHostingController + } + public override init(frame: CGRect) { super.init(frame: frame) _init() @@ -133,6 +148,7 @@ extension MediaView { imageView.translatesAutoresizingMaskIntoConstraints = false container.addSubview(imageView) imageView.pinToParent() + layoutAlt() } private func bindImage(configuration: Configuration, info: Configuration.ImageInfo) { @@ -151,6 +167,9 @@ extension MediaView { self.imageView.image = image } .store(in: &configuration.disposeBag) + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = info.altDescription + } } private func layoutGIF() { @@ -161,6 +180,8 @@ extension MediaView { setupIndicatorViewHierarchy() playerIndicatorLabel.attributedText = NSAttributedString(string: "GIF") + + layoutAlt() } private func bindGIF(configuration: Configuration, info: Configuration.VideoInfo) { @@ -171,6 +192,9 @@ extension MediaView { // auto play for GIF player.play() + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = info.altDescription + } } private func layoutVideo() { @@ -223,6 +247,14 @@ extension MediaView { .store(in: &_disposeBag) } + private func layoutAlt() { + if #available(iOS 15.0, *) { + altViewController.view.translatesAutoresizingMaskIntoConstraints = false + container.addSubview(altViewController.view) + altViewController.view.pinToParent() + } + } + public func prepareForReuse() { _disposeBag.removeAll() @@ -258,6 +290,10 @@ extension MediaView { container.removeFromSuperview() container.removeConstraints(container.constraints) + if #available(iOS 15.0, *) { + altViewController.rootView.altDescription = nil + } + // reset configuration configuration = nil } From 4bcf76740f11c98c739c888fb0969da1a6657114 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 12:36:31 -0500 Subject: [PATCH 680/733] Render alt text --- .../View/Content/MediaAltTextOverlay.swift | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index 91aeb8993..173fe53ac 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -14,15 +14,33 @@ struct MediaAltTextOverlay: View { @State private var showingAlt = false var body: some View { - HStack { - VStack { - Spacer(minLength: 0) - if altDescription != nil { - Button("ALT") {} - .buttonStyle(AltButtonStyle()) + GeometryReader { geom in + ZStack { + if let altDescription { + if showingAlt { + HStack(alignment: .top) { + Text(altDescription) + Spacer() + Button(action: { showingAlt = false }) { + Image(systemName: "xmark.circle.fill") + .frame(width: 20, height: 20) + } + } + .padding(8) + .frame(width: geom.size.width) + .fixedSize() + } else { + Button("ALT") { showingAlt = true } + .fixedSize() + .buttonStyle(AltButtonStyle()) + } } } - Spacer(minLength: 0) + .foregroundColor(.white) + .tint(.white) + .background(Color.black.opacity(0.85)) + .cornerRadius(4) + .frame(width: geom.size.width, height: geom.size.height, alignment: .bottomLeading) } .padding(.horizontal, 16) .padding(.vertical, 8) @@ -34,29 +52,21 @@ struct MediaAltTextOverlay: View { @available(iOS 15.0, *) private struct AltButtonStyle: ButtonStyle { - @Environment(\.pixelLength) private var pixelLength func makeBody(configuration: Configuration) -> some View { configuration.label .font(.caption.weight(.semibold)) - .foregroundColor(.white) .padding(.horizontal, 8) .padding(.vertical, 3) - .background(Color.black.opacity(0.85)) - .cornerRadius(4) .opacity(configuration.isPressed ? 0.5 : 1) - .overlay( - .white.opacity(0.4), - in: RoundedRectangle(cornerRadius: 4) - .inset(by: -0.5) - .stroke(lineWidth: 0.5) - ) } } @available(iOS 15.0, *) struct MediaAltTextOverlay_Previews: PreviewProvider { static var previews: some View { - MediaAltTextOverlay(altDescription: nil) MediaAltTextOverlay(altDescription: "Hello, world!") + .frame(height: 300) + .background(Color.gray) + .previewLayout(.sizeThatFits) } } From 7235ba3fb28a0db04645f6e160858fb44e584343 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 12:36:43 -0500 Subject: [PATCH 681/733] Spring transition --- .../MastodonUI/View/Content/MediaAltTextOverlay.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index 173fe53ac..594ed48ae 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -12,6 +12,7 @@ struct MediaAltTextOverlay: View { var altDescription: String? @State private var showingAlt = false + @Namespace private var namespace var body: some View { GeometryReader { geom in @@ -26,13 +27,16 @@ struct MediaAltTextOverlay: View { .frame(width: 20, height: 20) } } + .transition(.scale(scale: 0.1, anchor: .bottomLeading)) .padding(8) .frame(width: geom.size.width) .fixedSize() + .matchedGeometryEffect(id: "background", in: namespace) } else { Button("ALT") { showingAlt = true } .fixedSize() .buttonStyle(AltButtonStyle()) + .matchedGeometryEffect(id: "background", in: namespace) } } } @@ -40,6 +44,7 @@ struct MediaAltTextOverlay: View { .tint(.white) .background(Color.black.opacity(0.85)) .cornerRadius(4) + .animation(.spring(response: 0.25), value: showingAlt) .frame(width: geom.size.width, height: geom.size.height, alignment: .bottomLeading) } .padding(.horizontal, 16) From 1461b314ff5cb916e119bd3060b97e1826648649 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 12:36:57 -0500 Subject: [PATCH 682/733] Add a thin white border --- .../MastodonUI/View/Content/MediaAltTextOverlay.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index 594ed48ae..09aeaa9e0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -44,6 +44,12 @@ struct MediaAltTextOverlay: View { .tint(.white) .background(Color.black.opacity(0.85)) .cornerRadius(4) + .overlay( + .white.opacity(0.5), + in: RoundedRectangle(cornerRadius: 4) + .inset(by: -0.5) + .stroke(lineWidth: 0.5) + ) .animation(.spring(response: 0.25), value: showingAlt) .frame(width: geom.size.width, height: geom.size.height, alignment: .bottomLeading) } From 019a9920f04b781068cbef5202e508f3c8f64d23 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 12:56:04 -0500 Subject: [PATCH 683/733] better animations? or at least different --- .../View/Content/MediaAltTextOverlay.swift | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index 09aeaa9e0..1bab0bc24 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -27,16 +27,22 @@ struct MediaAltTextOverlay: View { .frame(width: 20, height: 20) } } - .transition(.scale(scale: 0.1, anchor: .bottomLeading)) .padding(8) - .frame(width: geom.size.width) - .fixedSize() - .matchedGeometryEffect(id: "background", in: namespace) + .matchedGeometryEffect(id: "background", in: namespace, properties: .position) + .transition( + .scale(scale: 0.2, anchor: .bottomLeading) + .combined(with: .opacity) + ) } else { Button("ALT") { showingAlt = true } - .fixedSize() - .buttonStyle(AltButtonStyle()) - .matchedGeometryEffect(id: "background", in: namespace) + .font(.caption.weight(.semibold)) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .matchedGeometryEffect(id: "background", in: namespace, properties: .position) + .transition( + .scale(scale: 3, anchor: .trailing) + .combined(with: .opacity) + ) } } } @@ -50,7 +56,7 @@ struct MediaAltTextOverlay: View { .inset(by: -0.5) .stroke(lineWidth: 0.5) ) - .animation(.spring(response: 0.25), value: showingAlt) + .animation(.spring(response: 0.3), value: showingAlt) .frame(width: geom.size.width, height: geom.size.height, alignment: .bottomLeading) } .padding(.horizontal, 16) @@ -61,17 +67,6 @@ struct MediaAltTextOverlay: View { } } -@available(iOS 15.0, *) -private struct AltButtonStyle: ButtonStyle { - func makeBody(configuration: Configuration) -> some View { - configuration.label - .font(.caption.weight(.semibold)) - .padding(.horizontal, 8) - .padding(.vertical, 3) - .opacity(configuration.isPressed ? 0.5 : 1) - } -} - @available(iOS 15.0, *) struct MediaAltTextOverlay_Previews: PreviewProvider { static var previews: some View { From 042c4968322a362cf96d1a82cfb10dc92482db67 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 13:11:42 -0500 Subject: [PATCH 684/733] Fix image sizing --- .../Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index 1bab0bc24..fec17f1ee 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -24,6 +24,8 @@ struct MediaAltTextOverlay: View { Spacer() Button(action: { showingAlt = false }) { Image(systemName: "xmark.circle.fill") + .resizable() + .aspectRatio(contentMode: .fill) .frame(width: 20, height: 20) } } From 7553b0aae64fadf534f58ecc3c6ade7171ded3c1 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 13:23:14 -0500 Subject: [PATCH 685/733] Fix MediaView accessibility --- .../Sources/MastodonUI/View/Content/MediaView.swift | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 8ce96674e..814e48e6a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -127,18 +127,18 @@ extension MediaView { case .image(let info): layoutImage() bindImage(configuration: configuration, info: info) - accessibilityLabel = "Show image" // TODO: i18n + accessibilityHint = "Expands the image. Double-tap and hold to show actions" // TODO: i18n case .gif(let info): layoutGIF() bindGIF(configuration: configuration, info: info) - accessibilityLabel = "Show GIF" // TODO: i18n + accessibilityHint = "Expands the GIF. Double-tap and hold to show actions" // TODO: i18n case .video(let info): layoutVideo() bindVideo(configuration: configuration, info: info) - accessibilityLabel = "Show video player" // TODO: i18n + accessibilityHint = "Shows video player. Double-tap and hold to show actions" // TODO: i18n } - accessibilityHint = "Tap then hold to show menu" // TODO: i18n + accessibilityTraits.insert([.button, .image]) layoutBlurhash() bindBlurhash(configuration: configuration) @@ -167,6 +167,8 @@ extension MediaView { self.imageView.image = image } .store(in: &configuration.disposeBag) + + accessibilityLabel = info.altDescription if #available(iOS 15.0, *) { altViewController.rootView.altDescription = info.altDescription } @@ -192,6 +194,8 @@ extension MediaView { // auto play for GIF player.play() + + accessibilityLabel = info.altDescription if #available(iOS 15.0, *) { altViewController.rootView.altDescription = info.altDescription } From cd9e013a40555bde3382fd8a2fa1f156e02d84b9 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 14:01:46 -0500 Subject: [PATCH 686/733] Fix HUDButton hitTest method --- MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift index 78579bb1e..566100bb6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift @@ -68,6 +68,10 @@ public class HUDButton: UIView { } public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - button + if self.point(inside: point, with: event) { + return button + } else { + return nil + } } } From 6b041abd6f22d8be886ee22b18c2e36724968dd0 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Tue, 20 Dec 2022 12:59:40 -0600 Subject: [PATCH 687/733] Publish both static & dynamic libraries --- Mastodon.xcodeproj/project.pbxproj | 44 +++++++++++++++--------------- MastodonSDK/Package.swift | 28 ++++++++++++------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 50114c55b..b001db762 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -75,11 +75,11 @@ 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */; }; 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; }; 2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */; }; - 357FEE8729522CA50021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8629522CA50021C9DC /* MastodonSDK */; }; - 357FEE8829522CA50021C9DC /* MastodonSDK in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8629522CA50021C9DC /* MastodonSDK */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - 357FEE8A29522CB60021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8929522CB60021C9DC /* MastodonSDK */; }; - 357FEE8E29522CC00021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE8D29522CC00021C9DC /* MastodonSDK */; }; - 357FEE9229522CE60021C9DC /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEE9129522CE60021C9DC /* MastodonSDK */; }; + 357FEEAF29523D470021C9DC /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEEAE29523D470021C9DC /* MastodonSDKDynamic */; }; + 357FEEB029523D470021C9DC /* MastodonSDKDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 357FEEAE29523D470021C9DC /* MastodonSDKDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 357FEEB229523D510021C9DC /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEEB129523D510021C9DC /* MastodonSDKDynamic */; }; + 357FEEB629523D5C0021C9DC /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEEB529523D5C0021C9DC /* MastodonSDKDynamic */; }; + 357FEEBA29523D660021C9DC /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 357FEEB929523D660021C9DC /* MastodonSDKDynamic */; }; 5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */; }; 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */; }; 5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B90C456262599800002E742 /* SettingsViewModel.swift */; }; @@ -493,7 +493,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 357FEE8829522CA50021C9DC /* MastodonSDK in Embed Frameworks */, + 357FEEB029523D470021C9DC /* MastodonSDKDynamic in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -1087,7 +1087,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 357FEE8729522CA50021C9DC /* MastodonSDK in Frameworks */, + 357FEEAF29523D470021C9DC /* MastodonSDKDynamic in Frameworks */, DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */, 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */, ); @@ -1114,7 +1114,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 357FEE9229522CE60021C9DC /* MastodonSDK in Frameworks */, + 357FEEBA29523D660021C9DC /* MastodonSDKDynamic in Frameworks */, DB8FABC726AEC7B2008E5AF4 /* Intents.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1123,7 +1123,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 357FEE8E29522CC00021C9DC /* MastodonSDK in Frameworks */, + 357FEEB629523D5C0021C9DC /* MastodonSDKDynamic in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1131,7 +1131,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 357FEE8A29522CB60021C9DC /* MastodonSDK in Frameworks */, + 357FEEB229523D510021C9DC /* MastodonSDKDynamic in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2757,7 +2757,7 @@ ); name = Mastodon; packageProductDependencies = ( - 357FEE8629522CA50021C9DC /* MastodonSDK */, + 357FEEAE29523D470021C9DC /* MastodonSDKDynamic */, ); productName = Mastodon; productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */; @@ -2816,7 +2816,7 @@ ); name = MastodonIntent; packageProductDependencies = ( - 357FEE9129522CE60021C9DC /* MastodonSDK */, + 357FEEB929523D660021C9DC /* MastodonSDKDynamic */, ); productName = MastodonIntent; productReference = DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */; @@ -2836,7 +2836,7 @@ ); name = ShareActionExtension; packageProductDependencies = ( - 357FEE8D29522CC00021C9DC /* MastodonSDK */, + 357FEEB529523D5C0021C9DC /* MastodonSDKDynamic */, ); productName = ShareActionExtension; productReference = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */; @@ -2856,7 +2856,7 @@ ); name = NotificationService; packageProductDependencies = ( - 357FEE8929522CB60021C9DC /* MastodonSDK */, + 357FEEB129523D510021C9DC /* MastodonSDKDynamic */, ); productName = NotificationService; productReference = DBF8AE13263293E400C9C23C /* NotificationService.appex */; @@ -4644,21 +4644,21 @@ /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ - 357FEE8629522CA50021C9DC /* MastodonSDK */ = { + 357FEEAE29523D470021C9DC /* MastodonSDKDynamic */ = { isa = XCSwiftPackageProductDependency; - productName = MastodonSDK; + productName = MastodonSDKDynamic; }; - 357FEE8929522CB60021C9DC /* MastodonSDK */ = { + 357FEEB129523D510021C9DC /* MastodonSDKDynamic */ = { isa = XCSwiftPackageProductDependency; - productName = MastodonSDK; + productName = MastodonSDKDynamic; }; - 357FEE8D29522CC00021C9DC /* MastodonSDK */ = { + 357FEEB529523D5C0021C9DC /* MastodonSDKDynamic */ = { isa = XCSwiftPackageProductDependency; - productName = MastodonSDK; + productName = MastodonSDKDynamic; }; - 357FEE9129522CE60021C9DC /* MastodonSDK */ = { + 357FEEB929523D660021C9DC /* MastodonSDKDynamic */ = { isa = XCSwiftPackageProductDependency; - productName = MastodonSDK; + productName = MastodonSDKDynamic; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 7939f051e..9eca5e460 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -3,6 +3,17 @@ import PackageDescription +let publicLibraryTargets = [ + "CoreDataStack", + "MastodonAsset", + "MastodonCommon", + "MastodonCore", + "MastodonExtension", + "MastodonLocalization", + "MastodonSDK", + "MastodonUI", +] + let package = Package( name: "MastodonSDK", defaultLocalization: "en", @@ -10,19 +21,16 @@ let package = Package( .iOS(.v14), ], products: [ + // Static Library .library( name: "MastodonSDK", + targets: publicLibraryTargets + ), + // Dynamic Library + .library( + name: "MastodonSDKDynamic", type: .dynamic, - targets: [ - "CoreDataStack", - "MastodonAsset", - "MastodonCommon", - "MastodonCore", - "MastodonExtension", - "MastodonLocalization", - "MastodonSDK", - "MastodonUI", - ] + targets: publicLibraryTargets ) ], dependencies: [ From da8b6848b764536a156b309786cbd53e8b8909d5 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Tue, 20 Dec 2022 13:16:31 -0600 Subject: [PATCH 688/733] Exclude `Preview Assets.xcassets` from Release config --- Mastodon.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index b001db762..56ee3a4a4 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -3938,6 +3938,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; + EXCLUDED_SOURCE_FILE_NAMES = "Mastodon/Resources/Preview\\ Assets.xcassets"; INFOPLIST_FILE = Mastodon/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", From 5adce841efbdff8943a13d689ad3a66ecc23213d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 14:22:38 -0500 Subject: [PATCH 689/733] =?UTF-8?q?Label=20images=20as=20=E2=80=9C[alt],?= =?UTF-8?q?=20attachment=203=20of=204=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input/Base.lproj/app.json | 1 + Localization/app.json | 1 + .../Generated/Strings.swift | 4 +++ .../Resources/Base.lproj/Localizable.strings | 1 + .../Content/MediaView+Configuration.swift | 26 +++++++++++++---- .../MastodonUI/View/Content/MediaView.swift | 28 +++++++++++++------ 6 files changed, 46 insertions(+), 15 deletions(-) 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) From a9534e480aa305a4fa1955aa48163cfc46735461 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 14:44:49 -0500 Subject: [PATCH 690/733] FIx NewsView+Configuration.swift --- .../MastodonUI/View/Content/NewsView+Configuration.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift index 560721b74..8403be756 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift @@ -42,7 +42,9 @@ extension NewsView { assetURL: link.image, altDescription: nil )), - blurhash: link.blurhash + blurhash: link.blurhash, + index: 1, + total: 1 ) imageView.setup(configuration: configuration) From 2d606a52af8f4ba4dccc9a3a252d0fbff8c7d238 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 14:48:40 -0500 Subject: [PATCH 691/733] Remove unused DateToolsSwift dependency --- Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift | 1 - Podfile | 1 - Podfile.lock | 6 +----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index edd431e52..1bf54cdfe 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -14,7 +14,6 @@ import CoreData import CoreDataStack import GameplayKit import AlamofireImage -import DateToolsSwift import MastodonCore import MastodonUI diff --git a/Podfile b/Podfile index 4df2d4d7c..022d37082 100644 --- a/Podfile +++ b/Podfile @@ -12,7 +12,6 @@ target 'Mastodon' do # misc pod 'SwiftGen', '~> 6.6.2' - pod 'DateToolsSwift', '~> 5.0.0' pod 'Kanna', '~> 5.2.2' pod 'Sourcery', '~> 1.6.1' diff --git a/Podfile.lock b/Podfile.lock index c7220b00a..fd7dc267d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,5 +1,4 @@ PODS: - - DateToolsSwift (5.0.0) - FLEX (4.4.1) - Kanna (5.2.7) - Sourcery (1.6.1): @@ -9,7 +8,6 @@ PODS: - XLPagerTabStrip (9.0.0) DEPENDENCIES: - - DateToolsSwift (~> 5.0.0) - FLEX (~> 4.4.0) - Kanna (~> 5.2.2) - Sourcery (~> 1.6.1) @@ -18,7 +16,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - - DateToolsSwift - FLEX - Kanna - Sourcery @@ -26,13 +23,12 @@ SPEC REPOS: - XLPagerTabStrip SPEC CHECKSUMS: - DateToolsSwift: 4207ada6ad615d8dc076323d27037c94916dbfa6 FLEX: 7ca2c8cd3a435ff501ff6d2f2141e9bdc934eaab Kanna: 01cfbddc127f5ff0963692f285fcbc8a9d62d234 Sourcery: f3759f803bd0739f74fc92a4341eed0473ce61ac SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: 7499a197793f73c4dcf1d16a315434baaa688873 +PODFILE CHECKSUM: ae1bc4dc14863e27c79f4a0b2445696f037ef405 COCOAPODS: 1.11.3 From 2f553c16485320818db715ad98e4efa041ae7e93 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 16:07:03 -0500 Subject: [PATCH 692/733] Prevent reblogging DMs --- .../MastodonUI/View/Content/StatusView+ViewModel.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 3d261ba28..17b87166a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -160,13 +160,11 @@ extension StatusView { $isMyself ) .map { visibility, isMyself in - if isMyself { - return true - } - switch visibility { case .public, .unlisted: return true + case .private where isMyself: + return true case .private, .direct, ._other: return false } From 726af2e8ea6e5a313f7161c95f9eb04d269bdd0b Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 16:12:43 -0500 Subject: [PATCH 693/733] Fall back to allowing reblogs of unsupported visibilities --- .../MastodonUI/View/Content/StatusView+ViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 17b87166a..029eb540f 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -161,11 +161,11 @@ extension StatusView { ) .map { visibility, isMyself in switch visibility { - case .public, .unlisted: + case .public, .unlisted, ._other: return true case .private where isMyself: return true - case .private, .direct, ._other: + case .private, .direct: return false } } From 36b7e50f5b75f57ccb3662f4da93ebf31f8013f6 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 20 Dec 2022 18:17:47 -0500 Subject: [PATCH 694/733] Delete NotificationAvatarButton.swift --- Mastodon.xcodeproj/project.pbxproj | 12 --- .../Button/NotificationAvatarButton.swift | 86 ------------------- 2 files changed, 98 deletions(-) delete mode 100644 Mastodon/Scene/Notification/Button/NotificationAvatarButton.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 74b7841a5..ce12a4050 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -129,7 +129,6 @@ DB0618032785A7100030EE79 /* RegisterSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0618022785A7100030EE79 /* RegisterSection.swift */; }; DB0618052785A73D0030EE79 /* RegisterItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0618042785A73D0030EE79 /* RegisterItem.swift */; }; DB0A322E280EE9FD001729D2 /* DiscoveryIntroBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0A322D280EE9FD001729D2 /* DiscoveryIntroBannerView.swift */; }; - DB0C947726A7FE840088FB11 /* NotificationAvatarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C947626A7FE840088FB11 /* NotificationAvatarButton.swift */; }; DB0EF72B26FDB1D200347686 /* SidebarListCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0EF72A26FDB1D200347686 /* SidebarListCollectionViewCell.swift */; }; DB0EF72E26FDB24F00347686 /* SidebarListContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0EF72D26FDB24F00347686 /* SidebarListContentView.swift */; }; DB0F8150264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */; }; @@ -667,7 +666,6 @@ DB0618042785A73D0030EE79 /* RegisterItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterItem.swift; sourceTree = ""; }; DB0618062785A8880030EE79 /* MastodonRegisterViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonRegisterViewModel+Diffable.swift"; sourceTree = ""; }; DB0A322D280EE9FD001729D2 /* DiscoveryIntroBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryIntroBannerView.swift; sourceTree = ""; }; - DB0C947626A7FE840088FB11 /* NotificationAvatarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationAvatarButton.swift; sourceTree = ""; }; DB0EF72A26FDB1D200347686 /* SidebarListCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarListCollectionViewCell.swift; sourceTree = ""; }; DB0EF72D26FDB24F00347686 /* SidebarListContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarListContentView.swift; sourceTree = ""; }; DB0F814E264CFFD300F2A12B /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1635,14 +1633,6 @@ path = View; sourceTree = ""; }; - DB0C947826A7FE950088FB11 /* Button */ = { - isa = PBXGroup; - children = ( - DB0C947626A7FE840088FB11 /* NotificationAvatarButton.swift */, - ); - path = Button; - sourceTree = ""; - }; DB0EF72C26FDB1D600347686 /* View */ = { isa = PBXGroup; children = ( @@ -2393,7 +2383,6 @@ isa = PBXGroup; children = ( DB63F765279A5E5600455B82 /* NotificationTimeline */, - DB0C947826A7FE950088FB11 /* Button */, 2D35237F26256F470031AF25 /* Cell */, DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */, 2D607AD726242FC500B70763 /* NotificationViewModel.swift */, @@ -3274,7 +3263,6 @@ DB603113279EBEBA00A935FE /* DataSourceFacade+Block.swift in Sources */, DB63F777279A9A2A00455B82 /* NotificationView+Configuration.swift in Sources */, DB029E95266A20430062874E /* MastodonAuthenticationController.swift in Sources */, - DB0C947726A7FE840088FB11 /* NotificationAvatarButton.swift in Sources */, 5B90C461262599800002E742 /* SettingsLinkTableViewCell.swift in Sources */, DB6180DD263918E30018D199 /* MediaPreviewViewController.swift in Sources */, DBE3CDEC261C6B2900430CC6 /* FavoriteViewController.swift in Sources */, diff --git a/Mastodon/Scene/Notification/Button/NotificationAvatarButton.swift b/Mastodon/Scene/Notification/Button/NotificationAvatarButton.swift deleted file mode 100644 index 26abfbd23..000000000 --- a/Mastodon/Scene/Notification/Button/NotificationAvatarButton.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// NotificationAvatarButton.swift -// Mastodon -// -// Created by MainasuK Cirno on 2021-7-21. -// - -import UIKit -import FLAnimatedImage -import MastodonUI - -final class NotificationAvatarButton: AvatarButton { - - // Size fixed - static let containerSize = CGSize(width: 35, height: 35) - static let badgeImageViewSize = CGSize(width: 24, height: 24) - static let badgeImageMaskSize = CGSize(width: badgeImageViewSize.width + 4, height: badgeImageViewSize.height + 4) - - let badgeImageView: UIImageView = { - let imageView = RoundedImageView() - imageView.contentMode = .center - imageView.isOpaque = true - imageView.layer.shouldRasterize = true - imageView.layer.rasterizationScale = UIScreen.main.scale - return imageView - }() - - override func _init() { - super._init() - - size = CGSize(width: 35, height: 35) - - let path: CGPath = { - let path = CGMutablePath() - path.addRect(CGRect(origin: .zero, size: NotificationAvatarButton.containerSize)) - let x: CGFloat = { - if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft { - return -0.5 * NotificationAvatarButton.badgeImageMaskSize.width - } else { - return NotificationAvatarButton.containerSize.width - 0.5 * NotificationAvatarButton.badgeImageMaskSize.width - } - }() - path.addPath(UIBezierPath( - ovalIn: CGRect( - x: x, - y: NotificationAvatarButton.containerSize.height - 0.5 * NotificationAvatarButton.badgeImageMaskSize.width, - width: NotificationAvatarButton.badgeImageMaskSize.width, - height: NotificationAvatarButton.badgeImageMaskSize.height - ) - ).cgPath) - return path - }() - - let maskShapeLayer = CAShapeLayer() - maskShapeLayer.backgroundColor = UIColor.black.cgColor - maskShapeLayer.fillRule = .evenOdd - maskShapeLayer.path = path - avatarImageView.layer.mask = maskShapeLayer - - badgeImageView.translatesAutoresizingMaskIntoConstraints = false - addSubview(badgeImageView) - NSLayoutConstraint.activate([ - badgeImageView.centerXAnchor.constraint(equalTo: trailingAnchor), - badgeImageView.centerYAnchor.constraint(equalTo: bottomAnchor), - badgeImageView.widthAnchor.constraint(equalToConstant: NotificationAvatarButton.badgeImageViewSize.width).priority(.required - 1), - badgeImageView.heightAnchor.constraint(equalToConstant: NotificationAvatarButton.badgeImageViewSize.height).priority(.required - 1), - ]) - } - - override func updateAppearance() { - super.updateAppearance() - badgeImageView.alpha = primaryActionState.contains(.highlighted) ? 0.6 : 1.0 - } - -} - -final class RoundedImageView: UIImageView { - - override func layoutSubviews() { - super.layoutSubviews() - - layer.masksToBounds = true - layer.cornerRadius = bounds.width / 2 - layer.cornerCurve = .circular - } -} From cac163709590fd627524894e408470f38d05a311 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 21 Dec 2022 21:27:00 +0100 Subject: [PATCH 695/733] New Crowdin updates (#788) * New translations app.json (Korean) * New translations app.json (Swedish) * New translations app.json (Catalan) * New translations app.json (Icelandic) * New translations app.json (Slovenian) * New translations app.json (Italian) * New translations app.json (Galician) * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (Chinese Traditional) * New translations app.json (German) * New translations app.json (Spanish) * New translations app.json (Vietnamese) * New translations app.json (English) * New translations app.json (Latvian) * New translations app.json (Czech) * New translations app.json (Latvian) * New translations Localizable.stringsdict (Czech) * New translations Intents.stringsdict (Czech) * New translations app.json (French) * New translations app.json (Thai) * New translations app.json (Latvian) * New translations ios-infoPlist.json (Latvian) * New translations Localizable.stringsdict (Latvian) * New translations app.json (Spanish, Argentina) * New translations Localizable.stringsdict (Latvian) * New translations Intents.strings (Latvian) * New translations Intents.stringsdict (Latvian) * New translations app.json (Korean) * New translations app.json (French) * New translations app.json (Czech) * New translations app.json (Romanian) * New translations app.json (Spanish) * New translations app.json (Arabic) * New translations app.json (Catalan) * New translations app.json (Danish) * New translations app.json (German) * New translations app.json (Basque) * New translations app.json (Finnish) * New translations app.json (Italian) * New translations app.json (Japanese) * New translations app.json (Dutch) * New translations app.json (Hebrew) * New translations app.json (Slovenian) * New translations app.json (Chinese Traditional) * New translations app.json (Vietnamese) * New translations app.json (Kabyle) * New translations app.json (Swedish) * New translations app.json (Turkish) * New translations app.json (Ukrainian) * New translations app.json (Scottish Gaelic) * New translations app.json (Portuguese) * New translations app.json (Russian) * New translations app.json (Chinese Simplified) * New translations app.json (English) * New translations app.json (Galician) * New translations app.json (Portuguese, Brazilian) * New translations app.json (Indonesian) * New translations app.json (Spanish, Argentina) * New translations app.json (Thai) * New translations app.json (Latvian) * New translations app.json (Hindi) * New translations app.json (English, United States) * New translations app.json (Welsh) * New translations app.json (Sinhala) * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (Sorani (Kurdish)) * New translations app.json (Icelandic) * New translations app.json (Burmese) * New translations app.json (Aragonese) * New translations app.json (Slovenian) * New translations app.json (Catalan) * New translations app.json (Latvian) * New translations app.json (Welsh) * New translations app.json (Spanish, Argentina) * New translations app.json (Welsh) * New translations app.json (Icelandic) * New translations app.json (Swedish) * New translations app.json (French) * New translations app.json (Finnish) * New translations app.json (Arabic) * New translations app.json (Thai) * New translations app.json (Italian) * New translations app.json (Chinese Traditional) * New translations app.json (Galician) * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (German) * New translations app.json (Czech) --- .../input/cs.lproj/Intents.stringsdict | 2 +- .../Intents/input/lv.lproj/Intents.strings | 42 +- .../input/lv.lproj/Intents.stringsdict | 16 +- .../StringsConvertor/input/an.lproj/app.json | 9 +- .../StringsConvertor/input/ar.lproj/app.json | 23 +- .../StringsConvertor/input/ca.lproj/app.json | 13 +- .../StringsConvertor/input/ckb.lproj/app.json | 9 +- .../input/cs.lproj/Localizable.stringsdict | 2 +- .../StringsConvertor/input/cs.lproj/app.json | 39 +- .../StringsConvertor/input/cy.lproj/app.json | 37 +- .../StringsConvertor/input/da.lproj/app.json | 9 +- .../StringsConvertor/input/de.lproj/app.json | 13 +- .../input/en-US.lproj/app.json | 11 +- .../StringsConvertor/input/en.lproj/app.json | 11 +- .../input/es-AR.lproj/app.json | 13 +- .../StringsConvertor/input/es.lproj/app.json | 15 +- .../StringsConvertor/input/eu.lproj/app.json | 9 +- .../StringsConvertor/input/fi.lproj/app.json | 13 +- .../StringsConvertor/input/fr.lproj/app.json | 13 +- .../StringsConvertor/input/gd.lproj/app.json | 9 +- .../StringsConvertor/input/gl.lproj/app.json | 13 +- .../StringsConvertor/input/he.lproj/app.json | 9 +- .../StringsConvertor/input/hi.lproj/app.json | 9 +- .../StringsConvertor/input/id.lproj/app.json | 9 +- .../StringsConvertor/input/is.lproj/app.json | 15 +- .../StringsConvertor/input/it.lproj/app.json | 13 +- .../StringsConvertor/input/ja.lproj/app.json | 9 +- .../StringsConvertor/input/kab.lproj/app.json | 9 +- .../StringsConvertor/input/kmr.lproj/app.json | 21 +- .../StringsConvertor/input/ko.lproj/app.json | 13 +- .../input/lv.lproj/Localizable.stringsdict | 174 ++++---- .../StringsConvertor/input/lv.lproj/app.json | 395 +++++++++--------- .../input/lv.lproj/ios-infoPlist.json | 8 +- .../StringsConvertor/input/my.lproj/app.json | 9 +- .../StringsConvertor/input/nl.lproj/app.json | 9 +- .../input/pt-BR.lproj/app.json | 9 +- .../StringsConvertor/input/pt.lproj/app.json | 9 +- .../StringsConvertor/input/ro.lproj/app.json | 9 +- .../StringsConvertor/input/ru.lproj/app.json | 9 +- .../StringsConvertor/input/si.lproj/app.json | 9 +- .../StringsConvertor/input/sl.lproj/app.json | 15 +- .../StringsConvertor/input/sv.lproj/app.json | 13 +- .../StringsConvertor/input/th.lproj/app.json | 15 +- .../StringsConvertor/input/tr.lproj/app.json | 9 +- .../StringsConvertor/input/uk.lproj/app.json | 9 +- .../StringsConvertor/input/vi.lproj/app.json | 13 +- .../input/zh-Hans.lproj/app.json | 9 +- .../input/zh-Hant.lproj/app.json | 13 +- 48 files changed, 645 insertions(+), 519 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/cs.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/cs.lproj/Intents.stringsdict index deea8db12..29249b2cc 100644 --- a/Localization/StringsConvertor/Intents/input/cs.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/cs.lproj/Intents.stringsdict @@ -25,7 +25,7 @@ There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Existuje %#@count_option@ odpovídající „${visibility}“. count_option NSStringFormatSpecTypeKey diff --git a/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.strings index eddd2026f..fdd529eee 100644 --- a/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.strings @@ -1,51 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Publicē Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Teksta Saturu"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Publicē Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Kādu saturu publicēt?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Publicēšana neizdevās"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Neizdošanās Iemesls"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Sūtīt Ziņu ar teksta saturu"; "RxSqsb" = "Ziņa"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Publicēt ${content} Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Ziņa"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Redzamība"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Ziņu Redzamība"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Ir ${count} opcijas, kas atbilst “Publisks”."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Ir ${count} opcijas, kas atbilst “Tikai Sekotājiem”."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Publisks"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Tikai Sekotājiem"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Publicē Mastodon"; "dYQ5NN" = "Publisks"; "ehFLjY" = "Tikai sekotājiem"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Publicēšana neizdevās. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Ziņa tika veiksmīgi nosūtīta."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Tikai apstiprinājumam, tu vēlējies \"Publisks\"?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Tikai apstiprinājumam, tu vēlējies \"Tikai Sekotājiem\"?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Ziņa tika veiksmīgi nosūtīta. "; diff --git a/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.stringsdict index 8926678aa..2461fec49 100644 --- a/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/lv.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + Ir %#@count_option@, kas atbilst “${content}”. count_option NSStringFormatSpecTypeKey @@ -13,17 +13,17 @@ NSStringFormatValueTypeKey %ld zero - %ld options + %ld opciju one - 1 option + 1 opcija other - %ld options + %ld opcijas There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Ir %#@count_option@, kas atbilst “${visibility}”. count_option NSStringFormatSpecTypeKey @@ -31,11 +31,11 @@ NSStringFormatValueTypeKey %ld zero - %ld options + %ld izvēles one - 1 option + 1 izvēle other - %ld options + %ld izvēles diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 84463895e..b0e090cf0 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Te sigue" }, "dashboard": { - "posts": "publicacions", - "following": "seguindo", - "followers": "seguidores" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index e752a79e5..c27cf8b70 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -99,8 +99,8 @@ "settings": "الإعدادات", "delete": "حذف", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "الترجَمَة مِن %s", + "unknown_language": "غير مَعرُوفة" } }, "tabs": { @@ -142,7 +142,7 @@ "sensitive_content": "مُحتَوى حَسَّاس", "media_content_warning": "اُنقُر لِلكَشف", "tap_to_reveal": "اُنقُر لِلكَشف", - "load_embed": "Load Embed", + "load_embed": "تحميل المُضمَن", "link_via_user": "%s via %s", "poll": { "vote": "صَوِّت", @@ -165,7 +165,7 @@ "show_image": "أظْهِرِ الصُّورَة", "show_gif": "أظْهِر GIF", "show_video_player": "أظْهِر مُشَغِّلَ المَقاطِعِ المَرئِيَّة", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "مُشارَكَة الرابِط فِي مَنشور", "tap_then_hold_to_show_menu": "اُنقُر مُطَوَّلًا لِإظْهَارِ القائِمَة" }, "tag": { @@ -183,9 +183,9 @@ "direct": "المُستخدمِونَ المُشارِ إليهم فَقَطْ مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", + "translated_from": "الترجَمَة مِن %s بِاستِخدَام %s", + "unknown_language": "غير مَعرُوفة", + "unknown_provider": "غير مَعرُوف", "show_original": "Shown Original" } }, @@ -463,9 +463,12 @@ "follows_you": "يُتابِعُك" }, "dashboard": { - "posts": "مَنشورات", - "following": "مُتابَع", - "followers": "مُتابِع" + "my_posts": "مَنشورات", + "my_following": "مُتابَعُون", + "my_followers": "مُتابِعُون", + "other_posts": "مَنشورات", + "other_following": "مُتابَعُون", + "other_followers": "مُتابِعُون" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 81b9c49db..3222ec984 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Només l'usuari mencionat pot veure aquesta publicació." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Traduït del %s fent servir %s", "unknown_language": "Desconegut", - "unknown_provider": "Unknown", + "unknown_provider": "Desconegut", "show_original": "Mostra l'original" } }, @@ -463,9 +463,12 @@ "follows_you": "Et segueix" }, "dashboard": { - "posts": "tuts", - "following": "seguint", - "followers": "seguidors" + "my_posts": "tuts", + "my_following": "seguint", + "my_followers": "seguidors", + "other_posts": "tuts", + "other_following": "seguint", + "other_followers": "seguidors" }, "fields": { "joined": "S'hi va unir", diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 693c8e9f6..e7222d645 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "پۆستەکان", - "following": "شوێنکەوتن", - "followers": "شوێنکەوتوو" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/cs.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/cs.lproj/Localizable.stringsdict index 6e44e9f0a..63e324a1b 100644 --- a/Localization/StringsConvertor/input/cs.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cs.lproj/Localizable.stringsdict @@ -65,7 +65,7 @@ a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ zbývá character_count NSStringFormatSpecTypeKey diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 0c210fa37..30d5eb26c 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -53,8 +53,8 @@ "message": "Úspěšně vyčištěno %s mezipaměti." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Poznámka", + "message": "Překlad se nezdařil. Správce možná nepovolil překlad na tomto serveru nebo tento server používá starší verzi Mastodonu, kde překlady ještě nejsou podporovány.", "button": "OK" } }, @@ -83,7 +83,7 @@ "sign_up": "Vytvořit účet", "see_more": "Zobrazit více", "preview": "Náhled", - "copy": "Copy", + "copy": "Kopírovat", "share": "Sdílet", "share_user": "Sdílet %s", "share_post": "Sdílet příspěvek", @@ -99,13 +99,13 @@ "settings": "Nastavení", "delete": "Smazat", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Přeložit z %s", + "unknown_language": "Neznámý" } }, "tabs": { "home": "Domů", - "search_and_explore": "Search and Explore", + "search_and_explore": "Hledat a zkoumat", "notifications": "Oznámení", "profile": "Profil" }, @@ -124,7 +124,7 @@ "open_reblogger_profile": "Otevřít rebloggerův profil", "reply_status": "Odpovědět na příspěvek", "toggle_reblog": "Přepnout Reblog na příspěvku", - "toggle_favorite": "Toggle Favorite on Post", + "toggle_favorite": "Přepnout Oblíbené na příspěvku", "toggle_content_warning": "Přepnout varování obsahu", "preview_image": "Náhled obrázku" }, @@ -142,8 +142,8 @@ "sensitive_content": "Citlivý obsah", "media_content_warning": "Klepnutím kdekoli zobrazíte", "tap_to_reveal": "Klepnutím zobrazit", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Načíst vložené", + "link_via_user": "%s přes %s", "poll": { "vote": "Hlasovat", "closed": "Uzavřeno" @@ -165,7 +165,7 @@ "show_image": "Zobrazit obrázek", "show_gif": "Zobrazit GIF", "show_video_player": "Zobrazit video přehrávač", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Sdílet odkaz v příspěvku", "tap_then_hold_to_show_menu": "Klepnutím podržte pro zobrazení nabídky" }, "tag": { @@ -183,10 +183,10 @@ "direct": "Pouze zmíněný uživatel může vidět tento příspěvek." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Shown Original" + "translated_from": "Přeloženo z %s pomocí %s", + "unknown_language": "Neznámý", + "unknown_provider": "Neznámý", + "show_original": "Zobrazit originál" } }, "friendship": { @@ -463,12 +463,15 @@ "follows_you": "Sleduje vás" }, "dashboard": { - "posts": "příspěvky", - "following": "sledování", - "followers": "sledující" + "my_posts": "příspěvky", + "my_following": "sledování", + "my_followers": "sledující", + "other_posts": "příspěvky", + "other_following": "sledování", + "other_followers": "sledující" }, "fields": { - "joined": "Joined", + "joined": "Připojen/a", "add_row": "Přidat řádek", "placeholder": { "label": "Označení", diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 0838ef9ff..b276dfa4b 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -53,9 +53,9 @@ "message": "Cliriwyd storfa %s yn llwyddiannus." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "title": "Nodyn", + "message": "Methwyd cyfieithu. Efallai nad yw'r gweinyddwr wedi galluogi cyfieithiadau ar y gweinydd hwn neu mae'r gweinydd hwn yn rhedeg fersiwn hŷn o Mastodon lle nad yw cyfieithiadau ar gael eto.", + "button": "Iawn" } }, "controls": { @@ -83,7 +83,7 @@ "sign_up": "Creu cyfrif", "see_more": "Gweld Mwy", "preview": "Rhagolwg", - "copy": "Copy", + "copy": "Copïo", "share": "Rhannu", "share_user": "Rhannu %s", "share_post": "Rhannu Tŵt", @@ -99,8 +99,8 @@ "settings": "Gosodiadau", "delete": "Dileu", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Cyfieithu o %s", + "unknown_language": "Anhysbys" } }, "tabs": { @@ -142,8 +142,8 @@ "sensitive_content": "Cynnwys Sensitif", "media_content_warning": "Tapiwch unrhywle i weld", "tap_to_reveal": "Tapiwch i weld", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "load_embed": "Llwytho Planiad", + "link_via_user": "%s trwy %s", "poll": { "vote": "Pleidleisio", "closed": "Wedi cau" @@ -165,7 +165,7 @@ "show_image": "Dangos llun", "show_gif": "Dangos GIF", "show_video_player": "Dangos chwaraewr fideo", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Rhannu'r Ddolen yn y Postiad", "tap_then_hold_to_show_menu": "Tapiwch a gwasgu i gael y ddewislen" }, "tag": { @@ -183,10 +183,10 @@ "direct": "Dim ond y ddefnyddiwr â soniwyd sy'n gallu gweld y post hwn." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Shown Original" + "translated_from": "Cyfieithwyd o %s gan ddefnyddio %s", + "unknown_language": "Anhysbys", + "unknown_provider": "Anhysbys", + "show_original": "Dangos y Gwreiddiol" } }, "friendship": { @@ -463,12 +463,15 @@ "follows_you": "Yn eich dilyn" }, "dashboard": { - "posts": "postiadau", - "following": "yn dilyn", - "followers": "dilynwyr" + "my_posts": "postiadu", + "my_following": "yn dilyn", + "my_followers": "dilynwyr", + "other_posts": "postiadu", + "other_following": "yn dilyn", + "other_followers": "dilynwyr" }, "fields": { - "joined": "Joined", + "joined": "Ymunwyd", "add_row": "Ychwanegu Rhes", "placeholder": { "label": "Label", diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 8114a1bf4..4939d3afb 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index b50556f53..8c28db94f 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Nur erwähnte Benutzer können diesen Beitrag sehen." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Übersetzt von %s mit %s", "unknown_language": "Unbekannt", - "unknown_provider": "Unknown", + "unknown_provider": "Unbekannt", "show_original": "Original anzeigen" } }, @@ -463,9 +463,12 @@ "follows_you": "Folgt dir" }, "dashboard": { - "posts": "Beiträge", - "following": "Gefolgte", - "followers": "Folgende" + "my_posts": "Beiträge", + "my_following": "folge ich", + "my_followers": "followers", + "other_posts": "Beiträge", + "other_following": "folge ich", + "other_followers": "followers" }, "fields": { "joined": "Beigetreten", diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index b28aac1c7..b94b9df8a 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -463,12 +463,15 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { - "joined": "Liitytty", + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index b28aac1c7..b94b9df8a 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -463,12 +463,15 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { - "joined": "Liitytty", + "joined": "Joined", "add_row": "Add Row", "placeholder": { "label": "Label", diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index a494b2854..120460c44 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Traducido desde el %s vía %s", "unknown_language": "Desconocido", - "unknown_provider": "Unknown", + "unknown_provider": "Desconocido", "show_original": "Mostrar original" } }, @@ -463,9 +463,12 @@ "follows_you": "Te sigue" }, "dashboard": { - "posts": "mensajes", - "following": "siguiendo", - "followers": "seguidores" + "my_posts": "mensajes", + "my_following": "siguiendo", + "my_followers": "seguidores", + "other_posts": "mensajes", + "other_following": "siguiendo", + "other_followers": "seguidores" }, "fields": { "joined": "En este servidor desde", diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 894e752a6..6d19e833b 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Sólo el usuario mencionado puede ver este mensaje." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Traducido desde %s usando %s", "unknown_language": "Desconocido", - "unknown_provider": "Unknown", + "unknown_provider": "Desconocido", "show_original": "Mostrar Original" } }, @@ -463,12 +463,15 @@ "follows_you": "Te sigue" }, "dashboard": { - "posts": "publicaciones", - "following": "siguiendo", - "followers": "seguidores" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { - "joined": "Joined", + "joined": "Se unió", "add_row": "Añadir Fila", "placeholder": { "label": "Nombre para el campo", diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index f6ec71d44..e7c5021bb 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Jarraitzen zaitu" }, "dashboard": { - "posts": "bidalketa", - "following": "jarraitzen", - "followers": "jarraitzaile" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 9bdd23991..f6beff049 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Käännetty kielestä %s palvelulla %s", "unknown_language": "Unknown", - "unknown_provider": "Unknown", + "unknown_provider": "Tuntematon", "show_original": "Shown Original" } }, @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "julkaisut", - "following": "seurataan", - "followers": "seuraajat" + "my_posts": "julkaisut", + "my_following": "seurattavat", + "my_followers": "seuraajat", + "other_posts": "julkaisut", + "other_following": "seurattavat", + "other_followers": "seuraajat" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 1186e0549..1d998ba77 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Seul·e l’utilisateur·rice mentionnée peut voir ce message." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Traduit de %s en utilisant %s", "unknown_language": "Inconnu", - "unknown_provider": "Unknown", + "unknown_provider": "Inconnu", "show_original": "Afficher l’original" } }, @@ -463,9 +463,12 @@ "follows_you": "Vous suit" }, "dashboard": { - "posts": "publications", - "following": "abonnements", - "followers": "abonnés" + "my_posts": "messages", + "my_following": "abonnement", + "my_followers": "abonnés", + "other_posts": "publications", + "other_following": "abonnement", + "other_followers": "abonnés" }, "fields": { "joined": "Ici depuis", diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 5cea86c4b..5f27b8f00 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "’Gad leantainn" }, "dashboard": { - "posts": "postaichean", - "following": "a’ leantainn", - "followers": "luchd-leantainn" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index d3ded8866..f8bda509e 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Só a usuaria mencionada pode ver a publicación." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Traducido do %s usando %s", "unknown_language": "Descoñecido", - "unknown_provider": "Unknown", + "unknown_provider": "Descoñecido", "show_original": "Mostrar o orixinal" } }, @@ -463,9 +463,12 @@ "follows_you": "Séguete" }, "dashboard": { - "posts": "publicacións", - "following": "seguindo", - "followers": "seguidoras" + "my_posts": "publicacións", + "my_following": "seguindo", + "my_followers": "seguidoras", + "other_posts": "publicacións", + "other_following": "seguindo", + "other_followers": "seguidoras" }, "fields": { "joined": "Uniuse", diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 4d0bdbd5f..6b484e301 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 2b620f0a9..e7ea54abb 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index be121bb00..558dad5d1 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Mengikutimu" }, "dashboard": { - "posts": "postingan", - "following": "mengikuti", - "followers": "pengikut" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Bergabung", diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 29e4f45aa..3d01bd737 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -142,7 +142,7 @@ "sensitive_content": "Viðkvæmt efni", "media_content_warning": "Ýttu hvar sem er til að birta", "tap_to_reveal": "Ýttu til að birta", - "load_embed": "Load Embed", + "load_embed": "Hlaða inn ívöfnu", "link_via_user": "%s með %s", "poll": { "vote": "Greiða atkvæði", @@ -183,9 +183,9 @@ "direct": "Einungis notendur sem minnst er á geta séð þessa færslu." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Þýtt úr %s með %s", "unknown_language": "Óþekkt", - "unknown_provider": "Unknown", + "unknown_provider": "Óþekkt", "show_original": "Birta upprunalegt" } }, @@ -463,9 +463,12 @@ "follows_you": "Fylgist með þér" }, "dashboard": { - "posts": "færslur", - "following": "fylgist með", - "followers": "fylgjendur" + "my_posts": "færslur", + "my_following": "er fylgst með", + "my_followers": "fylgjendur", + "other_posts": "færslur", + "other_following": "er fylgst með", + "other_followers": "fylgjendur" }, "fields": { "joined": "Gerðist þátttakandi", diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 9eaae69d3..d355a4c10 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Solo l'utente menzionato può vedere questo post." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Tradotto da %s utilizzando %s", "unknown_language": "Sconosciuto", - "unknown_provider": "Unknown", + "unknown_provider": "Sconosciuto", "show_original": "Mostra l'originale" } }, @@ -463,9 +463,12 @@ "follows_you": "Ti segue" }, "dashboard": { - "posts": "post", - "following": "seguendo", - "followers": "seguaci" + "my_posts": "post", + "my_following": "seguendo", + "my_followers": "seguaci", + "other_posts": "post", + "other_following": "seguendo", + "other_followers": "seguaci" }, "fields": { "joined": "Profilo iscritto", diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 92440f927..c16f12dcf 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "フォローされています" }, "dashboard": { - "posts": "投稿", - "following": "フォロー", - "followers": "フォロワー" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 581b0f55a..720f979cb 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Yeṭṭafaṛ-ik•im" }, "dashboard": { - "posts": "tisuffaɣ", - "following": "iṭafaṛ", - "followers": "imeḍfaren" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index c1a4fdfdd..5e23f74b9 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -83,7 +83,7 @@ "sign_up": "Ajimêr biafirîne", "see_more": "Bêtir bibîne", "preview": "Pêşdîtin", - "copy": "Copy", + "copy": "Jê bigire", "share": "Parve bike", "share_user": "%s parve bike", "share_post": "Şandiyê parve bike", @@ -99,7 +99,7 @@ "settings": "Sazkarî", "delete": "Jê bibe", "translate_post": { - "title": "Ji %s hate wergerandin", + "title": "Ji %s wergerîne", "unknown_language": "Nenas" } }, @@ -143,7 +143,7 @@ "media_content_warning": "Ji bo eşkerekirinê li derekî bitikîne", "tap_to_reveal": "Ji bo dîtinê bitikîne", "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "link_via_user": "%s bi riya %s", "poll": { "vote": "Deng bide", "closed": "Girtî" @@ -165,7 +165,7 @@ "show_image": "Wêneyê nîşan bide", "show_gif": "GIF nîşan bide", "show_video_player": "Lêdera vîdyoyê nîşan bide", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Girêdanê di şandiyê de parve bike", "tap_then_hold_to_show_menu": "Ji bo nîşandana menuyê dirêj bitikîne" }, "tag": { @@ -183,9 +183,9 @@ "direct": "Tenê bikarhênerê qalkirî dikare vê şandiyê bibîne." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Hate wergerandin ji %s bi riya %s", "unknown_language": "Nenas", - "unknown_provider": "Unknown", + "unknown_provider": "Nenas", "show_original": "A resen nîşan bide" } }, @@ -463,9 +463,12 @@ "follows_you": "Te dişopîne" }, "dashboard": { - "posts": "şandî", - "following": "dişopîne", - "followers": "şopîner" + "my_posts": "şandî", + "my_following": "dişopîne", + "my_followers": "şopîner", + "other_posts": "şandî", + "other_following": "dişopîne", + "other_followers": "şopîner" }, "fields": { "joined": "Dîroka tevlîbûnê", diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 815af4cbb..7d4e48e09 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Only mentioned user can see this post." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "%s에서 %s를 사용해 번역됨", "unknown_language": "알 수 없음", - "unknown_provider": "Unknown", + "unknown_provider": "알 수 없음", "show_original": "원본 보기" } }, @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "게시물", - "following": "팔로잉", - "followers": "팔로워" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "가입일", diff --git a/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict index 0287a83a5..fd327d745 100644 --- a/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/lv.lproj/Localizable.stringsdict @@ -13,17 +13,17 @@ NSStringFormatValueTypeKey ld zero - %ld unread notifications + %ld nelasītu paziņojumu one - 1 unread notification + 1 nelasīts paziņojums other - %ld unread notifications + %ld nelasīti paziņojumi a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Ievades ierobežojums pārsniedz %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -31,17 +31,17 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld rakstzīmju one - 1 character + 1 rakstzīme other - %ld characters + %ld rakstzīmes a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Ievades ierobežojums paliek %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -49,17 +49,17 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld rakstzīmju one - 1 character + 1 rakstzīme other - %ld characters + %ld rakstzīmes a11y.plural.count.characters_left NSStringLocalizedFormatKey - %#@character_count@ left + %#@character_count@ palikušas character_count NSStringFormatSpecTypeKey @@ -67,11 +67,11 @@ NSStringFormatValueTypeKey ld zero - %ld characters + %ld rakstzīmju one - 1 character + 1 rakstzīme other - %ld characters + %ld rakstzīmes plural.count.followed_by_and_mutual @@ -98,11 +98,11 @@ NSStringFormatValueTypeKey ld zero - Followed by %1$@, and %ld mutuals + Seko %1$@ un %ld kopīgi one - Followed by %1$@, and another mutual + Seko %1$@ un vēl viens kopīgs other - Followed by %1$@, and %ld mutuals + Seko %1$@ un %ld kopīgi plural.count.metric_formatted.post @@ -116,11 +116,11 @@ NSStringFormatValueTypeKey ld zero - posts + ziņu one - post + ziņa other - posts + ziņas plural.count.media @@ -134,11 +134,11 @@ NSStringFormatValueTypeKey ld zero - %ld media + %ld multivide one - 1 media + 1 multivide other - %ld media + %ld multivide plural.count.post @@ -152,11 +152,11 @@ NSStringFormatValueTypeKey ld zero - %ld posts + %ld ziņu one - 1 post + 1 ziņa other - %ld posts + %ld ziņas plural.count.favorite @@ -170,11 +170,11 @@ NSStringFormatValueTypeKey ld zero - %ld favorites + %ld iecienītu one - 1 favorite + 1 iecienīts other - %ld favorites + %ld iecienīti plural.count.reblog @@ -188,11 +188,11 @@ NSStringFormatValueTypeKey ld zero - %ld reblogs + %ld reblogu one - 1 reblog + 1 reblogs other - %ld reblogs + %ld reblogi plural.count.reply @@ -206,11 +206,11 @@ NSStringFormatValueTypeKey ld zero - %ld replies + %ld atbilžu one - 1 reply + 1 atbilde other - %ld replies + %ld atbildes plural.count.vote @@ -224,11 +224,11 @@ NSStringFormatValueTypeKey ld zero - %ld votes + %ld balsu one - 1 vote + 1 balss other - %ld votes + %ld balsis plural.count.voter @@ -242,11 +242,11 @@ NSStringFormatValueTypeKey ld zero - %ld voters + %ld balsotāju one - 1 voter + 1 balsotājs other - %ld voters + %ld balsotāji plural.people_talking @@ -260,11 +260,11 @@ NSStringFormatValueTypeKey ld zero - %ld people talking + %ld cilvēku apspriež one - 1 people talking + 1 cilvēks apspriež other - %ld people talking + %ld cilvēki apspriež plural.count.following @@ -278,11 +278,11 @@ NSStringFormatValueTypeKey ld zero - %ld following + %ld sekotāju one - 1 following + 1 sekotājs other - %ld following + %ld sekotāji plural.count.follower @@ -296,11 +296,11 @@ NSStringFormatValueTypeKey ld zero - %ld followers + %ld sekotāju one - 1 follower + 1 sekotājs other - %ld followers + %ld sekotāji date.year.left @@ -314,11 +314,11 @@ NSStringFormatValueTypeKey ld zero - %ld years left + palicis %ld gadu one - 1 year left + palicis 1 gads other - %ld years left + palikuši %ld gadi date.month.left @@ -332,11 +332,11 @@ NSStringFormatValueTypeKey ld zero - %ld months left + palicis %ld mēnešu one - 1 months left + palicis 1 mēnesis other - %ld months left + palikuši %ld mēneši date.day.left @@ -350,11 +350,11 @@ NSStringFormatValueTypeKey ld zero - %ld days left + palikušas %ld dienas one - 1 day left + palikusi 1 diena other - %ld days left + palikušas %ld dienas date.hour.left @@ -368,11 +368,11 @@ NSStringFormatValueTypeKey ld zero - %ld hours left + atlikušas %ld stundas one - 1 hour left + atlikusi 1 stunda other - %ld hours left + atlikušas %ld stundas date.minute.left @@ -386,11 +386,11 @@ NSStringFormatValueTypeKey ld zero - %ld minutes left + atlikušas %ld minūtes one - 1 minute left + atlikusi 1 minūte other - %ld minutes left + atlikušas %ld minūtes date.second.left @@ -404,11 +404,11 @@ NSStringFormatValueTypeKey ld zero - %ld seconds left + atlikušas %ld sekundes one - 1 second left + atlikusi 1 sekunde other - %ld seconds left + atlikušas %ld sekundes date.year.ago.abbr @@ -422,11 +422,11 @@ NSStringFormatValueTypeKey ld zero - %ldy ago + pirms %ld g. one - 1y ago + pirms 1 g. other - %ldy ago + pirms %ld g. date.month.ago.abbr @@ -440,11 +440,11 @@ NSStringFormatValueTypeKey ld zero - %ldM ago + pirms %ld M. one - 1M ago + pirms 1 M. other - %ldM ago + pirms %ld M. date.day.ago.abbr @@ -458,11 +458,11 @@ NSStringFormatValueTypeKey ld zero - %ldd ago + pirms %ld d. one - 1d ago + pirms 1 d. other - %ldd ago + pirms %ld d. date.hour.ago.abbr @@ -476,11 +476,11 @@ NSStringFormatValueTypeKey ld zero - %ldh ago + pirms %ld st. one - 1h ago + pirms 1 st. other - %ldh ago + pirms %ld st. date.minute.ago.abbr @@ -494,11 +494,11 @@ NSStringFormatValueTypeKey ld zero - %ldm ago + pirms %ld m. one - 1m ago + pirms 1 m. other - %ldm ago + pirms %ld m. date.second.ago.abbr @@ -512,11 +512,11 @@ NSStringFormatValueTypeKey ld zero - %lds ago + pirms %ld s. one - 1s ago + pirms 1 s. other - %lds ago + pirms %ld s. diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 5a8cc6df6..01a8d0515 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -121,9 +121,9 @@ "next_status": "Nākamā Ziņa", "open_status": "Atvērt Ziņu", "open_author_profile": "Atvērt Autora Profilu", - "open_reblogger_profile": "Atvērt Pārpublicētāja Profilu", + "open_reblogger_profile": "Atvērt Reblogotāja Profilu", "reply_status": "Atbildēt uz Ziņu", - "toggle_reblog": "Pārslēgt Atbilde uz Ziņu", + "toggle_reblog": "Pārslēgt Reblogs uz Ziņu", "toggle_favorite": "Pārslēgt Izlasi uz Ziņas", "toggle_content_warning": "Pārslēgt Satura Brīdinājumu", "preview_image": "Priekšskata attēls" @@ -134,7 +134,7 @@ } }, "status": { - "user_reblogged": "%s pārpublicēja", + "user_reblogged": "%s reblogoja", "user_replied_to": "Atbildēja %s", "show_post": "Parādīt Ziņu", "show_user_profile": "Parādīt lietotāja profilu", @@ -157,36 +157,36 @@ "actions": { "reply": "Atbildēt", "reblog": "Reblogot", - "unreblog": "Atsaukt pārpublicēšanu", + "unreblog": "Atsaukt reblogu", "favorite": "Izlase", "unfavorite": "Izņemt no izlases", "menu": "Izvēlne", "hide": "Slēpt", "show_image": "Rādīt attēlu", "show_gif": "Rādīt GIF", - "show_video_player": "Show video player", - "share_link_in_post": "Share Link in Post", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "show_video_player": "Rādīt video atskaņotāju", + "share_link_in_post": "Kopīgot Saiti Ziņā", + "tap_then_hold_to_show_menu": "Pieskaries un turi, lai parādītu izvēlni" }, "tag": { "url": "URL", "mention": "Pieminēt", "link": "Saite", - "hashtag": "Hashtag", + "hashtag": "Tēmturis", "email": "E-pasts", "emoji": "Emocijzīmes" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "Ikviens var redzēt šo ziņu, bet to nevar parādīt publiskajā laikrindā.", + "private": "Šo ziņu var redzēt tikai viņu sekotāji.", + "private_from_me": "Šo ziņu var redzēt tikai mani sekotāji.", + "direct": "Šo ziņu var redzēt tikai minētais lietotājs." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Shown Original" + "translated_from": "Tulkots no %s, izmantojot %s", + "unknown_language": "Nezināms", + "unknown_provider": "Nezināms", + "show_original": "Parādīts Oriģināls" } }, "friendship": { @@ -205,9 +205,9 @@ "unmute": "Noņemt apklusinājumu", "unmute_user": "Noņemt apklusinājumu @%s", "muted": "Apklusināts", - "edit_info": "Edit Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "edit_info": "Rediģēt", + "show_reblogs": "Rādīt Reblogus", + "hide_reblogs": "Paslēpt Reblogus" }, "timeline": { "filtered": "Filtrēts", @@ -215,48 +215,48 @@ "now": "Tagad" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", + "load_missing_posts": "Ielādēt trūkstošās ziņas", + "loading_missing_posts": "Ielādē trūkstošās ziņas...", "show_more_replies": "Rādīt vairāk atbildes" }, "header": { - "no_status_found": "No Post Found", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "no_status_found": "Nav Atrastu Ziņu", + "blocking_warning": "Tu nevari skatīt šī lietotāja profilu,\nlīdz tu tos atbloķē.\nTavs profils viņiem izskatās šādi.", + "user_blocking_warning": "Tu nevari skatīt %s profilu,\nlīdz tu tos atbloķē.\nTavs profils viņiem izskatās šādi.", + "blocked_warning": "Tu nevari skatīt šī lietotāja profilu\nlīdz tie tevi atbloķē.", + "user_blocked_warning": "Tu nevari skatīt %s profilu,\nlīdz tie tevi atbloķē.", + "suspended_warning": "Šī lietotāja darbība ir apturēta.", + "user_suspended_warning": "%s konta darbība ir apturēta." } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Get Started", + "slogan": "Sociālie tīkli\natpakaļ tavās rokās.", + "get_started": "Sāc", "log_in": "Pieteikties" }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "Laipni lūdzam atpakaļ", + "subtitle": "Piesakies serverī, kurā izveidoji savu kontu.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Ievadi URL vai meklē savu serveri" } }, "server_picker": { - "title": "Mastodon is made of users in different servers.", - "subtitle": "Pick a server based on your region, interests, or a general purpose one. You can still chat with anyone on Mastodon, regardless of your servers.", + "title": "Mastodon veido lietotāji dažādos serveros.", + "subtitle": "Izvēlieties serveri, pamatojoties uz savu reģionu, interesēm vai vispārīgu mērķi. Tu joprojām vari tērzēt ar jebkuru Mastodon lietotāju neatkarīgi no taviem serveriem.", "button": { "category": { "all": "Visi", "all_accessiblity_description": "Katekorija: Visi", - "academia": "academia", - "activism": "activism", + "academia": "akadēmija", + "activism": "aktīvisms", "food": "ēdiens", - "furry": "furry", + "furry": "pūkains", "games": "spēles", - "general": "general", + "general": "galvenais", "journalism": "žurnālisms", "lgbt": "lgbt", "regional": "regionāli", @@ -273,17 +273,17 @@ "category": "KATEGORIJA" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Meklēt kopienas vai ievadīt URL" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", + "finding_servers": "Meklē piejamos serverus...", + "bad_network": "Ielādējot datus, radās problēma. Pārbaudi interneta savienojumu.", "no_results": "Nav rezultātu" } }, "register": { - "title": "Let’s get you set up on %s", - "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", + "title": "Ļauj tevi iestatīt %s", + "lets_get_you_set_up_on_domain": "Ļauj tevi iestatīt %s", "input": { "avatar": { "delete": "Dzēst" @@ -300,7 +300,7 @@ }, "password": { "placeholder": "parole", - "require": "Your password needs at least:", + "require": "Tavai parolei ir nepieciešams vismaz:", "character_limit": "8 rakstzīmes", "accessibility": { "checked": "atzīmēts", @@ -322,29 +322,29 @@ "reason": "Iemesls" }, "reason": { - "blocked": "%s contains a disallowed email provider", + "blocked": "%s satur neatļautu e-pasta pakalpojumu sniedzēju", "unreachable": "%s šķiet, ka neeksistē", "taken": "%s jau tiek izmantots", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", + "reserved": "%s ir rezervēts atslēgvārds", + "accepted": "%s jābūt apstiprinātām", "blank": "%s ir obligāts", "invalid": "%s ir nederīgs", "too_long": "%s ir pārāk garaš", "too_short": "%s ir pārāk īs", - "inclusion": "%s is not a supported value" + "inclusion": "%s nav atbalstīta vērtība" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", - "password_too_short": "Password is too short (must be at least 8 characters)" + "username_invalid": "Lietotājvārdā drīkst būt tikai burtciparu rakstzīmes un zemsvītras", + "username_too_long": "Lietotājvārds ir par garu (nedrīkst būt garāks par 30 rakstzīmēm)", + "email_invalid": "Šī nav derīga e-pasta adrese", + "password_too_short": "Parole ir pārāk īsa (jābūt vismaz 8 rakstzīmēm)" } } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", + "title": "Daži pamatnoteikumi.", + "subtitle": "Tos iestata un ievieš %s moderatori.", + "prompt": "Turpinot, uz tevi attiecas %s pakalpojumu sniegšanas noteikumi un konfidencialitātes politika.", "terms_of_service": "pakalpojuma noteikumi", "privacy_policy": "privātuma nosacījumi", "button": { @@ -352,45 +352,45 @@ } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", + "title": "Pēdējā lieta.", + "subtitle": "Pieskaries saitei, ko nosūtījām tev pa e-pastu, lai verificētu savu kontu.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Pieskaries saitei, ko nosūtījām tev pa e-pastu, lai verificētu savu kontu", "button": { - "open_email_app": "Open Email App", + "open_email_app": "Atvērt E-pasta Lietotni", "resend": "Nosūtīt atkārtoti" }, "dont_receive_email": { "title": "Pārbaudi savu e-pastu", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "description": "Pārbaudi, vai tava e-pasta adrese ir pareiza, kā arī savu mēstuļu mapi, ja tā nav.", "resend_email": "Atkārtoti nosūtīt e-pastu" }, "open_email_app": { - "title": "Check your inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", - "mail": "Mail", - "open_email_client": "Open Email Client" + "title": "Pārbaudi savu iesūtni.", + "description": "Mēs tikko nosūtījām tev e-pastu. Pārbaudi savu mēstuļu mapi, ja neesi to saņēmis.", + "mail": "Pasts", + "open_email_client": "Atvērt E-pasta Klientu" } }, "home_timeline": { - "title": "Home", + "title": "Sākums", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "Bezsaistē", + "new_posts": "Skatīt jaunās ziņas", + "published": "Publicēts!", + "Publishing": "Publicē ziņu...", "accessibility": { - "logo_label": "Logo Button", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_label": "Logotipa Poga", + "logo_hint": "Pieskaries, lai ritinātu uz augšu, un vēlreiz pieskaries iepriekšējai atrašanās vietai" } } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Atrodi Cilvēkus kam Sekot", + "follow_explain": "Kad seko kādam, tu redzēsi viņu ziņas savā mājas plūsmā." }, "compose": { "title": { - "new_post": "New Post", + "new_post": "Jauna Ziņa", "new_reply": "Jauna atbilde" }, "media_selection": { @@ -398,36 +398,36 @@ "photo_library": "Attēlu krātuve", "browse": "Pārlūkot" }, - "content_input_placeholder": "Type or paste what’s on your mind", + "content_input_placeholder": "Ieraksti vai ielīmē to, ko domā", "compose_action": "Publicēt", - "replying_to_user": "replying to %s", + "replying_to_user": "atbildot uz %s", "attachment": { "photo": "attēls", "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "attachment_broken": "Šis %s ir salauzts un nevar tikt augšuplādēts Mastodon.", + "description_photo": "Apraksti fotoattēlu vājredzīgajiem...", + "description_video": "Apraksti video vājredzīgajiem...", + "load_failed": "Ielāde Neizdevās", + "upload_failed": "Augšupielāde Neizdevās", + "can_not_recognize_this_media_attachment": "Nevar atpazīt šo multivides pielikumu", + "attachment_too_large": "Pārāk liels pielikums", + "compressing_state": "Saspiež...", + "server_processing_state": "Notiek servera apstrāde..." }, "poll": { - "duration_time": "Duration: %s", + "duration_time": "Ilgums: %s", "thirty_minutes": "30 minūtes", "one_hour": "1 Stunda", "six_hours": "6 stundas", "one_day": "1 Diena", "three_days": "3 Dienas", "seven_days": "7 Dienas", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option" + "option_number": "Izvēle %ld", + "the_poll_is_invalid": "Aptauja nav derīga", + "the_poll_has_empty_option": "Aptaujai ir tukša opcija" }, "content_warning": { - "placeholder": "Write an accurate warning here..." + "placeholder": "Uzraksti šeit precīzu brīdinājumu..." }, "visibility": { "public": "Publisks", @@ -436,26 +436,26 @@ "direct": "Tikai cilvēki, kurus es pieminu" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Vieta, ko pievienot" }, "accessibility": { "append_attachment": "Pievienot pielikumu", "append_poll": "Pievienot aptauju", "remove_poll": "Noņemt aptauju", - "custom_emoji_picker": "Custom Emoji Picker", - "enable_content_warning": "Enable Content Warning", - "disable_content_warning": "Disable Content Warning", - "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "custom_emoji_picker": "Pielāgoto Emocijzīmju Atlasītājs", + "enable_content_warning": "Iespējot Satura Brīdinājumu", + "disable_content_warning": "Atspējot Satura Brīdinājumu", + "post_visibility_menu": "Ziņu Redzamības Izvēlne", + "post_options": "Ziņas Iespējas", + "posting_as": "Publicēt kā %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", - "toggle_poll": "Toggle Poll", - "toggle_content_warning": "Toggle Content Warning", + "discard_post": "Izmest Ziņu", + "publish_post": "Publicēt Ziņu", + "toggle_poll": "Pārslēgt Aptauju", + "toggle_content_warning": "Pārslēgt Satura Brīdinājumu", "append_attachment_entry": "Pievienot pielikumu - %s", - "select_visibility_entry": "Select Visibility - %s" + "select_visibility_entry": "Atlasīt Redzamību — %s" } }, "profile": { @@ -463,24 +463,27 @@ "follows_you": "Seko tev" }, "dashboard": { - "posts": "posts", - "following": "seko", - "followers": "sekottāji" + "my_posts": "ziņas", + "my_following": "seko", + "my_followers": "sekotāji", + "other_posts": "ziņas", + "other_following": "seko", + "other_followers": "sekotāji" }, "fields": { - "joined": "Joined", + "joined": "Pievienojās", "add_row": "Pievienot rindu", "placeholder": { - "label": "Label", + "label": "Marķējums", "content": "Saturs" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Pārbaudīts %s", + "long": "Šīs saites piederība tika pārbaudīta %s" } }, "segmented_control": { - "posts": "Posts", + "posts": "Ziņas", "replies": "Atbildes", "posts_and_replies": "Ziņas un atbildes", "media": "Multivide", @@ -488,97 +491,97 @@ }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Izslēgt Kontu", + "message": "Apstiprināt, lai izslēgtu %s skaņu" }, "confirm_unmute_user": { - "title": "Unmute Account", - "message": "Confirm to unmute %s" + "title": "Ieslēgt Kontu", + "message": "Apstiprināt, lai ieslēgtu %s skaņu" }, "confirm_block_user": { "title": "Bloķēts kontu", - "message": "Confirm to block %s" + "message": "Apstiprināt, lai bloķētu %s" }, "confirm_unblock_user": { "title": "Atbloķēt kontu", "message": "Apstiprini lai atbloķētu %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Rādīt Reblogus", + "message": "Apstiprināt, lai rādītu reblogus" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Paslēpt Reblogus", + "message": "Apstiprināt, lai slēptu reblogus" } }, "accessibility": { - "show_avatar_image": "Show avatar image", - "edit_avatar_image": "Edit avatar image", - "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "show_avatar_image": "Rādīt avatara attēlu", + "edit_avatar_image": "Rediģēt avatara attēlu", + "show_banner_image": "Rādīt bannera attēlu", + "double_tap_to_open_the_list": "Dubultskāriens, lai atvērtu sarakstu" } }, "follower": { "title": "sekottājs", - "footer": "Followers from other servers are not displayed." + "footer": "Sekotāji no citiem serveriem netiek rādīti." }, "following": { "title": "seko", - "footer": "Follows from other servers are not displayed." + "footer": "Sekojumi no citiem serveriem netiek rādīti." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Tev pazīstamie sekotāji", + "followed_by_names": "Seko %s" }, "favorited_by": { - "title": "Favorited By" + "title": "Pievienoja izlasei" }, "reblogged_by": { - "title": "Reblogged By" + "title": "Reblogoja" }, "search": { "title": "Meklēt", "search_bar": { - "placeholder": "Search hashtags and users", + "placeholder": "Meklēt tēmturus un lietotājus", "cancel": "Atcelt" }, "recommend": { "button_text": "Skatīt visu", "hash_tag": { - "title": "Trending on Mastodon", - "description": "Hashtags that are getting quite a bit of attention", - "people_talking": "%s people are talking" + "title": "Tendences vietnē Mastodon", + "description": "Tēmturi, kuriem tiek pievērsta diezgan liela uzmanība", + "people_talking": "%s cilvēki apspriež" }, "accounts": { - "title": "Accounts you might like", - "description": "You may like to follow these accounts", - "follow": "Follow" + "title": "Konti, kuri tev varētu patikt", + "description": "Iespējams, tu vēlēsies sekot šiem kontiem", + "follow": "Sekot" } }, "searching": { "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" + "all": "Visi", + "people": "Cilvēki", + "hashtags": "Tēmturi", + "posts": "Ziņas" }, "empty_state": { - "no_results": "No results" + "no_results": "Nav rezultātu" }, - "recent_search": "Recent searches", - "clear": "Clear" + "recent_search": "Nesen meklētais", + "clear": "Notīrīt" } }, "discovery": { "tabs": { "posts": "Ziņas", - "hashtags": "Hashtags", + "hashtags": "Tēmturi", "news": "Ziņas", - "community": "Community", + "community": "Kopiena", "for_you": "Priekš tevis" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Šīs ir ziņas, kas iekaro tavu Mastodon stūrīti." }, "favorite": { "title": "Tava izlase" @@ -589,16 +592,16 @@ "Mentions": "Pieminējumi" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", - "reblogged_your_post": "reblogged your post", + "followed_you": "tev sekoja", + "favorited_your_post": "izcēla tavu ziņu", + "reblogged_your_post": "reblogoja tavu ziņu", "mentioned_you": "pieminēja tevi", - "request_to_follow_you": "request to follow you", + "request_to_follow_you": "lūgums tev sekot", "poll_has_ended": "balsošana beidzās" }, "keyobard": { "show_everything": "Parādīt man visu", - "show_mentions": "Show Mentions" + "show_mentions": "Rādīt Pieminējumus" }, "follow_request": { "accept": "Pieņemt", @@ -609,7 +612,7 @@ }, "thread": { "back_title": "Ziņa", - "title": "Post from %s" + "title": "Ziņa no %s" }, "settings": { "title": "Iestatījumi", @@ -622,42 +625,42 @@ }, "look_and_feel": { "title": "Izskats", - "use_system": "Use System", + "use_system": "Lietot Sistēmas", "really_dark": "Ļoti tumšs", "sorta_dark": "Itkā tumšs", "light": "Gaišs" }, "notifications": { "title": "Paziņojumi", - "favorites": "Favorites my post", + "favorites": "Izceļ manu ziņu", "follows": "Seko man", - "boosts": "Reblogs my post", + "boosts": "Reblogo manu ziņu", "mentions": "Pieminējumi", "trigger": { "anyone": "jebkurš", "follower": "sekottājs", - "follow": "anyone I follow", + "follow": "jebkurš, kam sekoju", "noone": "neviens", - "title": "Notify me when" + "title": "Paziņot man, kad" } }, "preference": { "title": "Uzstādījumi", - "true_black_dark_mode": "True black dark mode", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", - "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "true_black_dark_mode": "Īsti melns tumšais režīms", + "disable_avatar_animation": "Atspējot animētos avatarus", + "disable_emoji_animation": "Atspējot animētās emocijzīmes", + "using_default_browser": "Saišu atvēršana noklusētajā pārlūkā", + "open_links_in_mastodon": "Atvērt saites Mastodon" }, "boring_zone": { - "title": "The Boring Zone", + "title": "Garlaicīgā zona", "account_settings": "Konta iestatījumi", "terms": "Pakalpojuma noteikumi", "privacy": "Privātuma politika" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", + "title": "Pikantā zona", + "clear": "Notīrīt Multivides Kešatmiņu", "signout": "Iziet" } }, @@ -665,7 +668,7 @@ "mastodon_description": "Mastodon ir atvērtā koda programmatūra. Tu vari ziņot par problēmām GitHub %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Aizvērt Iestatījumu Logu" } }, "report": { @@ -673,24 +676,24 @@ "title": "Ziņot %s", "step1": "1. solis no 2", "step2": "2. solis no 2", - "content1": "Are there any other posts you’d like to add to the report?", - "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", + "content1": "Vai ir vēl kādas ziņas, kuras vēlies pievienot pārskatam?", + "content2": "Vai moderatoriem ir kaut kas jāzina par šo ziņojumu?", + "report_sent_title": "Paldies, ka ziņoji, mēs to izskatīsim.", "send": "Nosūtīt Sūdzību", "skip_to_send": "Sūtīt bez komentāra", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED", + "text_placeholder": "Ieraksti vai ielīmē papildu komentārus", + "reported": "ZIŅOTS", "step_one": { "step_1_of_4": "1. solis no 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", + "whats_wrong_with_this_post": "Kas vainas šim ierakstam?", + "whats_wrong_with_this_account": "Kas vainas šim kontam?", + "whats_wrong_with_this_username": "Kas vainas %s?", "select_the_best_match": "Izvēlieties labāko atbilstību", "i_dont_like_it": "Man tas nepatīk", "it_is_not_something_you_want_to_see": "Tas nav kaut kas, ko tu vēlies redzēt", "its_spam": "Tas ir spams", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", + "malicious_links_fake_engagement_or_repetetive_replies": "Ļaunprātīgas saites, viltus iesaistīšana vai atkārtotas atbildes", + "it_violates_server_rules": "Tas pārkāpj servera noteikumus", "you_are_aware_that_it_breaks_specific_rules": "Tu zini, ka tas pārkāpj īpašus noteikumus", "its_something_else": "Tas ir kaut kas cits", "the_issue_does_not_fit_into_other_categories": "Šis jautājums neietilpst citās kategorijās" @@ -699,7 +702,7 @@ "step_2_of_4": "2. solis no 4", "which_rules_are_being_violated": "Kuri noteikumi tiek pārkāpti?", "select_all_that_apply": "Atlasi visus atbilstošos", - "i_just_don’t_like_it": "I just don’t like it" + "i_just_don’t_like_it": "Man vienkārši tas nepatīk" }, "step_three": { "step_3_of_4": "3. solis no 4", @@ -712,47 +715,47 @@ }, "step_final": { "dont_want_to_see_this": "Vai nevēlies to redzēt?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Kad pakalpojumā Mastodon redzi kaut ko, kas tev nepatīk, tu vari noņemt šo personu no savas pieredzes.", "unfollow": "Atsekot", "unfollowed": "Atsekoja", "unfollow_user": "Atsekot %s", "mute_user": "Apklusināt %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Tu neredzēsi viņu ziņas vai reblogus savā mājas plūsmā. Viņi nezinās, ka ir izslēgti.", "block_user": "Bloķēt %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Viņi vairs nevarēs sekot tavām ziņām vai redzēt tās, taču varēs redzēt, vai viņi ir bloķēti.", "while_we_review_this_you_can_take_action_against_user": "Kamēr mēs to izskatām, tu vari veikt darbības pret @%s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Aizvērt Priekšskatījumu", + "show_next": "Rādīt Nākamo", + "show_previous": "Rādīt Iepriekšējo" } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", - "dismiss_account_switcher": "Dismiss Account Switcher", + "tab_bar_hint": "Pašreizējais atlasītais profils: %s. Veic dubultskārienu un pēc tam turi, lai parādītu konta pārslēdzēju", + "dismiss_account_switcher": "Noraidīt Konta Pārslēdzēju", "add_account": "Pievienot kontu" }, "wizard": { - "new_in_mastodon": "New in Mastodon", - "multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.", - "accessibility_hint": "Double tap to dismiss this wizard" + "new_in_mastodon": "Jaunums Mastodonā", + "multiple_account_switch_intro_description": "Pārslēdzies starp vairākiem kontiem, turot nospiestu profila pogu.", + "accessibility_hint": "Veic dubultskārienu, lai noraidītu šo vedni" }, "bookmark": { - "title": "Bookmarks" + "title": "Grāmatzīmes" }, "followed_tags": { - "title": "Followed Tags", + "title": "Sekotie Tēmturi", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "ziņas", + "participants": "dalībnieki", + "posts_today": "ziņas šodien" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Sekot", + "unfollow": "Atsekot" } } } diff --git a/Localization/StringsConvertor/input/lv.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/lv.lproj/ios-infoPlist.json index c6db73de0..860333e51 100644 --- a/Localization/StringsConvertor/input/lv.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/lv.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" + "NSCameraUsageDescription": "Izmanto, lai fotografētu ziņas statusu", + "NSPhotoLibraryAddUsageDescription": "Izmanto, lai saglabātu fotoattēlu Photo Library", + "NewPostShortcutItemTitle": "Jauna Ziņa", + "SearchShortcutItemTitle": "Meklēt" } diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 2b86c884a..ea235fa53 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 740e4f211..938f40a07 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Volgt jou" }, "dashboard": { - "posts": "berichten", - "following": "volgend", - "followers": "volgers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 7c0128f39..e680db924 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Segue você" }, "dashboard": { - "posts": "toots", - "following": "seguindo", - "followers": "seguidores" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 8114a1bf4..4939d3afb 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index a17e3b1e8..65ae8eb4e 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index ac8b73246..bb34e4c1c 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Подписан(а) на вас" }, "dashboard": { - "posts": "посты", - "following": "подписки", - "followers": "подписчики" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index cdeec5d49..364708892 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Follows You" }, "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 92013ea33..3ce4e2daa 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Samo omenjeni uporabnik lahko vidi to objavo." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Prevedeno iz %s s pomočjo %s", "unknown_language": "Neznano", - "unknown_provider": "Unknown", + "unknown_provider": "Neznano", "show_original": "Pokaži izvirnik" } }, @@ -463,12 +463,15 @@ "follows_you": "Vam sledi" }, "dashboard": { - "posts": "Objave", - "following": "sledi", - "followers": "sledilcev" + "my_posts": "objav", + "my_following": "sledi", + "my_followers": "sledilcev", + "other_posts": "objav", + "other_following": "sledi", + "other_followers": "sledilcev" }, "fields": { - "joined": "Joined", + "joined": "Pridružen_a", "add_row": "Dodaj vrstico", "placeholder": { "label": "Oznaka", diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index aaf76d01b..400758cd9 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Endast omnämnda användare kan se detta inlägg." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Översatt från %s med %s", "unknown_language": "Okänt", - "unknown_provider": "Unknown", + "unknown_provider": "Okänd", "show_original": "Visa original" } }, @@ -463,9 +463,12 @@ "follows_you": "Följer dig" }, "dashboard": { - "posts": "inlägg", - "following": "följer", - "followers": "följare" + "my_posts": "inlägg", + "my_following": "följer", + "my_followers": "följare", + "other_posts": "inlägg", + "other_following": "följer", + "other_followers": "följare" }, "fields": { "joined": "Gick med", diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 32e79f756..6b3421d47 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -183,9 +183,9 @@ "direct": "เฉพาะผู้ใช้ที่กล่าวถึงเท่านั้นที่สามารถเห็นโพสต์นี้" }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "แปลจาก %s โดยใช้ %s", "unknown_language": "ไม่รู้จัก", - "unknown_provider": "Unknown", + "unknown_provider": "ไม่รู้จัก", "show_original": "แสดงดั้งเดิมอยู่" } }, @@ -463,12 +463,15 @@ "follows_you": "ติดตามคุณ" }, "dashboard": { - "posts": "โพสต์", - "following": "กำลังติดตาม", - "followers": "ผู้ติดตาม" + "my_posts": "โพสต์", + "my_following": "กำลังติดตาม", + "my_followers": "ผู้ติดตาม", + "other_posts": "โพสต์", + "other_following": "กำลังติดตาม", + "other_followers": "ผู้ติดตาม" }, "fields": { - "joined": "Joined", + "joined": "เข้าร่วมเมื่อ", "add_row": "เพิ่มแถว", "placeholder": { "label": "ป้ายชื่อ", diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index fe7e63984..c22c6a3f9 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Seni takip ediyor" }, "dashboard": { - "posts": "gönderiler", - "following": "takip ediliyor", - "followers": "takipçi" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 25c28e5d7..230d61f7c 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "Підписаний(-на) на вас" }, "dashboard": { - "posts": "дописів", - "following": "підписаний", - "followers": "підписників" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 37c30ca20..3a3c66a66 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -183,9 +183,9 @@ "direct": "Chỉ người được nhắc đến có thể thấy tút." }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "Dịch từ %s bằng %s", "unknown_language": "Không xác định", - "unknown_provider": "Unknown", + "unknown_provider": "Không biết", "show_original": "Bản gốc" } }, @@ -463,9 +463,12 @@ "follows_you": "Đang theo dõi bạn" }, "dashboard": { - "posts": "tút", - "following": "theo dõi", - "followers": "người theo dõi" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Đã tham gia", diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index a7dae16b2..efe5c422e 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -463,9 +463,12 @@ "follows_you": "关注了你" }, "dashboard": { - "posts": "帖子", - "following": "正在关注", - "followers": "关注者" + "my_posts": "posts", + "my_following": "following", + "my_followers": "followers", + "other_posts": "posts", + "other_following": "following", + "other_followers": "followers" }, "fields": { "joined": "Joined", diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index b94e42bc6..711084407 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -183,9 +183,9 @@ "direct": "只有被提及的使用者能看到此嘟文。" }, "translation": { - "translated_from": "Translated from %s using %s", + "translated_from": "透過 %s 翻譯 %s", "unknown_language": "未知", - "unknown_provider": "Unknown", + "unknown_provider": "未知", "show_original": "顯示原文" } }, @@ -463,9 +463,12 @@ "follows_you": "跟隨了您" }, "dashboard": { - "posts": "嘟文", - "following": "跟隨中", - "followers": "跟隨者" + "my_posts": "嘟文", + "my_following": "正在跟隨", + "my_followers": "跟隨者", + "other_posts": "嘟文", + "other_following": "正在跟隨", + "other_followers": "跟隨者" }, "fields": { "joined": "加入時間", From e4848d21e5e637f5d13fe0faa5d48e0c77795fe2 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 21 Dec 2022 15:41:18 -0500 Subject: [PATCH 696/733] Improve handling of transparent avatars + avatar press state (#802) * Fix Podfile.lock checksum * Fix layout of avatarButton inside of border * Set a background for the avatar button in profile headers --- .../Scene/Profile/Header/View/ProfileHeaderView.swift | 10 ++++++---- Podfile.lock | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index cf2443552..ccc3dbe9f 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -243,11 +243,13 @@ final class ProfileHeaderView: UIView { extension ProfileHeaderView { private func _init() { backgroundColor = ThemeService.shared.currentTheme.value.systemBackgroundColor + avatarButton.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor ThemeService.shared.currentTheme .receive(on: DispatchQueue.main) .sink { [weak self] theme in guard let self = self else { return } self.backgroundColor = theme.systemBackgroundColor + self.avatarButton.backgroundColor = theme.secondarySystemBackgroundColor } .store(in: &_disposeBag) @@ -322,10 +324,10 @@ extension ProfileHeaderView { avatarButton.translatesAutoresizingMaskIntoConstraints = false avatarImageViewBackgroundView.addSubview(avatarButton) NSLayoutConstraint.activate([ - avatarButton.topAnchor.constraint(equalTo: avatarImageViewBackgroundView.topAnchor, constant: 0.5 * ProfileHeaderView.avatarImageViewBorderWidth), - avatarButton.leadingAnchor.constraint(equalTo: avatarImageViewBackgroundView.leadingAnchor, constant: 0.5 * ProfileHeaderView.avatarImageViewBorderWidth), - avatarImageViewBackgroundView.trailingAnchor.constraint(equalTo: avatarButton.trailingAnchor, constant: 0.5 * ProfileHeaderView.avatarImageViewBorderWidth), - avatarImageViewBackgroundView.bottomAnchor.constraint(equalTo: avatarButton.bottomAnchor, constant: 0.5 * ProfileHeaderView.avatarImageViewBorderWidth), + avatarButton.topAnchor.constraint(equalTo: avatarImageViewBackgroundView.topAnchor, constant: ProfileHeaderView.avatarImageViewBorderWidth), + avatarButton.leadingAnchor.constraint(equalTo: avatarImageViewBackgroundView.leadingAnchor, constant: ProfileHeaderView.avatarImageViewBorderWidth), + avatarImageViewBackgroundView.trailingAnchor.constraint(equalTo: avatarButton.trailingAnchor, constant: ProfileHeaderView.avatarImageViewBorderWidth), + avatarImageViewBackgroundView.bottomAnchor.constraint(equalTo: avatarButton.bottomAnchor, constant: ProfileHeaderView.avatarImageViewBorderWidth), avatarButton.widthAnchor.constraint(equalToConstant: ProfileHeaderView.avatarImageViewSize.width).priority(.required - 1), avatarButton.heightAnchor.constraint(equalToConstant: ProfileHeaderView.avatarImageViewSize.height).priority(.required - 1), ]) diff --git a/Podfile.lock b/Podfile.lock index fd7dc267d..cff1861dd 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -29,6 +29,6 @@ SPEC CHECKSUMS: SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: ae1bc4dc14863e27c79f4a0b2445696f037ef405 +PODFILE CHECKSUM: 9bca0a8bef019bda7253d8b5cdbce4c53a141398 COCOAPODS: 1.11.3 From 7eebb6226717bcc87e51b367601d738fc9205e68 Mon Sep 17 00:00:00 2001 From: Mary Date: Wed, 21 Dec 2022 23:06:49 +0100 Subject: [PATCH 697/733] Accept missing metadata on attachments Akkoma/Pleroma (and Friendica until recently) aren't providing attachment meta information like width or height. Because Mastodon app enforced those fields to be present, attachments would be filtered out. This commit change the behaviour of Mastodon.Entity.Status.mastodonAttachments by allowing those values to be missing and use default values instead. --- .../CoreDataStack/Status+Property.swift | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift index c4508a997..ca4fa9fc9 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift @@ -51,14 +51,28 @@ extension Mastodon.Entity.Status { guard let mediaAttachments = mediaAttachments else { return [] } let attachments = mediaAttachments.compactMap { media -> MastodonAttachment? in - guard let kind = media.attachmentKind, - let meta = media.meta, - let original = meta.original, - let width = original.width, // audio has width/height - let height = original.height + guard let kind = media.attachmentKind else { return nil } - - let durationMS: Int? = original.duration.flatMap { Int($0 * 1000) } + + let width: Int; + let height: Int; + let durationMS: Int?; + + if let meta = media.meta, + let original = meta.original, + let originalWidth = original.width, + let originalHeight = original.height { + width = originalWidth; // audio has width/height + height = originalHeight; + durationMS = original.duration.flatMap { Int($0 * 1000) } + } + else { + // In case metadata field is missing, use default values. + width = 32; + height = 32; + durationMS = nil; + } + return MastodonAttachment( id: media.id, kind: kind, From ff502a48684a7901d60d214e8fac8aea2f5d5b7e Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 21 Dec 2022 19:25:39 -0500 Subject: [PATCH 698/733] Remove some os_logs --- Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index d4a415f5f..4ff54934b 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -192,12 +192,10 @@ extension MediaPreviewViewController { extension MediaPreviewViewController { @objc private func closeButtonPressed(_ sender: UIButton) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) dismiss(animated: true, completion: nil) } @objc private func altButtonPressed(_ sender: UIButton) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) guard let alt = viewModel.altText else { return } present(AltViewController(alt: alt, sourceView: sender), animated: true) } From dc6a86f846132ae6e6474c80b1661a84ddf98d3c Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 21 Dec 2022 19:29:12 -0500 Subject: [PATCH 699/733] Extract out TouchTransparentStackView --- .../MediaPreviewViewController.swift | 16 ------------ .../Container/TouchTransparentStackView.swift | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 16 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Container/TouchTransparentStackView.swift diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index 4ff54934b..658bca33d 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -26,22 +26,6 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency { let pagingViewController = MediaPreviewPagingViewController() let topToolbar: UIStackView = { - class TouchTransparentStackView: UIStackView { - // allow button hit boxes to grow outside of this view’s bounds - override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - subviews.contains { $0.point(inside: $0.convert(point, from: self), with: event) } - } - - // allow taps on blank areas to pass through - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - let view = super.hitTest(point, with: event) - if view == self { - return nil - } - return view - } - } - let stackView = TouchTransparentStackView() stackView.axis = .horizontal stackView.distribution = .equalSpacing diff --git a/MastodonSDK/Sources/MastodonUI/View/Container/TouchTransparentStackView.swift b/MastodonSDK/Sources/MastodonUI/View/Container/TouchTransparentStackView.swift new file mode 100644 index 000000000..e519c0cf7 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Container/TouchTransparentStackView.swift @@ -0,0 +1,26 @@ +// +// TouchTransparentStackView.swift +// +// +// Created by Jed Fox on 2022-12-21. +// + +import UIKit + +/// A subclass of `UIStackView` that allows touches that aren’t captured by any +/// of its subviews to pass through to views beneath this view in the Z-order. +public class TouchTransparentStackView: UIStackView { + // allow subview hit boxes to grow outside of this view’s bounds + public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + subviews.contains { $0.point(inside: $0.convert(point, from: self), with: event) } + } + + // allow taps on blank areas to pass through + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let view = super.hitTest(point, with: event) + if view == self { + return nil + } + return view + } +} From f5c6529341da0f3967c1f58e92b491311b7384ba Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 21 Dec 2022 19:38:05 -0500 Subject: [PATCH 700/733] i18n for accessibility hint --- .../StringsConvertor/input/Base.lproj/app.json | 7 ++++++- Localization/app.json | 7 ++++++- .../MastodonLocalization/Generated/Strings.swift | 16 ++++++++++++---- .../Resources/Base.lproj/Localizable.strings | 5 ++++- .../MastodonUI/View/Content/MediaView.swift | 8 ++++---- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 243d60b9a..2959c9597 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -144,7 +144,6 @@ "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" @@ -188,6 +187,12 @@ "unknown_language": "Unknown", "unknown_provider": "Unknown", "show_original": "Shown Original" + }, + "media": { + "accessibility_label": "%s, attachment %d of %d", + "expand_image_hint": "Expands the image. Double-tap and hold to show actions", + "expand_gif_hint": "Expands the GIF. Double-tap and hold to show actions", + "expand_video_hint": "Shows the video player. Double-tap and hold to show actions" } }, "friendship": { diff --git a/Localization/app.json b/Localization/app.json index 243d60b9a..2959c9597 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -144,7 +144,6 @@ "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" @@ -188,6 +187,12 @@ "unknown_language": "Unknown", "unknown_provider": "Unknown", "show_original": "Shown Original" + }, + "media": { + "accessibility_label": "%s, attachment %d of %d", + "expand_image_hint": "Expands the image. Double-tap and hold to show actions", + "expand_gif_hint": "Expands the GIF. Double-tap and hold to show actions", + "expand_video_hint": "Shows the video player. Double-tap and hold to show actions" } }, "friendship": { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 75f348a0c..a3466fad6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -298,10 +298,6 @@ 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 @@ -344,6 +340,18 @@ public enum L10n { /// Undo reblog public static let unreblog = L10n.tr("Localizable", "Common.Controls.Status.Actions.Unreblog", fallback: "Undo reblog") } + public enum Media { + /// %@, attachment %d of %d + public static func accessibilityLabel(_ p1: Any, _ p2: Int, _ p3: Int) -> String { + return L10n.tr("Localizable", "Common.Controls.Status.Media.AccessibilityLabel", String(describing: p1), p2, p3, fallback: "%@, attachment %d of %d") + } + /// Expands the GIF. Double-tap and hold to show actions + public static let expandGifHint = L10n.tr("Localizable", "Common.Controls.Status.Media.ExpandGifHint", fallback: "Expands the GIF. Double-tap and hold to show actions") + /// Expands the image. Double-tap and hold to show actions + public static let expandImageHint = L10n.tr("Localizable", "Common.Controls.Status.Media.ExpandImageHint", fallback: "Expands the image. Double-tap and hold to show actions") + /// Shows the video player. Double-tap and hold to show actions + public static let expandVideoHint = L10n.tr("Localizable", "Common.Controls.Status.Media.ExpandVideoHint", fallback: "Shows the video player. Double-tap and hold to show actions") + } public enum MetaEntity { /// Email address: %@ public static func email(_ p1: Any) -> String { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 830f887b8..5280f2dcd 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -116,8 +116,11 @@ Please check your internet connection."; "Common.Controls.Status.ContentWarning" = "Content Warning"; "Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Load Embed"; +"Common.Controls.Status.Media.AccessibilityLabel" = "%@, attachment %d of %d"; +"Common.Controls.Status.Media.ExpandGifHint" = "Expands the GIF. Double-tap and hold to show actions"; +"Common.Controls.Status.Media.ExpandImageHint" = "Expands the image. Double-tap and hold to show actions"; +"Common.Controls.Status.Media.ExpandVideoHint" = "Shows the video player. Double-tap and hold to show actions"; "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.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 1b471d34a..a140d9737 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -128,15 +128,15 @@ extension MediaView { case .image(let info): layoutImage() bindImage(configuration: configuration, info: info) - accessibilityHint = "Expands the image. Double-tap and hold to show actions" // TODO: i18n + accessibilityHint = L10n.Common.Controls.Status.Media.expandImageHint case .gif(let info): layoutGIF() bindGIF(configuration: configuration, info: info) - accessibilityHint = "Expands the GIF. Double-tap and hold to show actions" // TODO: i18n + accessibilityHint = L10n.Common.Controls.Status.Media.expandGifHint case .video(let info): layoutVideo() bindVideo(configuration: configuration, info: info) - accessibilityHint = "Shows video player. Double-tap and hold to show actions" // TODO: i18n + accessibilityHint = L10n.Common.Controls.Status.Media.expandVideoHint } accessibilityTraits.insert([.button, .image]) @@ -220,7 +220,7 @@ extension MediaView { private func bindAlt(configuration: Configuration, altDescription: String?) { if configuration.total > 1 { - accessibilityLabel = L10n.Common.Controls.Status.mediaLabel( + accessibilityLabel = L10n.Common.Controls.Status.Media.accessibilityLabel( altDescription ?? "", configuration.index + 1, configuration.total From c08be1e1dd47a5e481c2645d5f054af3f0b5fd27 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Thu, 22 Dec 2022 12:52:27 -0500 Subject: [PATCH 701/733] fix: corrected alt for title button --- .../HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 38b80fe28..69f04a956 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,7 +103,7 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Logo Button" // TODO :i18n + logoButton.accessibilityLabel = "Mastodon" // TODO :i18n logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" case .newPostButton: configureButton( From d09339ea20de33dab1ed73ecd12d0a645bb68cc1 Mon Sep 17 00:00:00 2001 From: Tommy Braccia Date: Thu, 22 Dec 2022 13:26:27 -0500 Subject: [PATCH 702/733] fix: updated to use vars from strings.swift --- .../View/HomeTimelineNavigationBarTitleView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift index 69f04a956..7e51057bc 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleView.swift @@ -103,8 +103,8 @@ extension HomeTimelineNavigationBarTitleView { logoButton.setImage(Asset.Asset.mastodonTextLogo.image.withRenderingMode(.alwaysTemplate), for: .normal) logoButton.contentMode = .center logoButton.isHidden = false - logoButton.accessibilityLabel = "Mastodon" // TODO :i18n - logoButton.accessibilityHint = "Tap to scroll to top and tap again to previous location" + logoButton.accessibilityLabel = L10n.Scene.HomeTimeline.NavigationBarState.Accessibility.logoLabel // TODO :i18n + logoButton.accessibilityHint = L10n.Scene.HomeTimeline.NavigationBarState.Accessibility.logoHint case .newPostButton: configureButton( title: L10n.Scene.HomeTimeline.NavigationBarState.newPosts, From 2a66afc52c666c9bbe61c3103ab5585fb6870f24 Mon Sep 17 00:00:00 2001 From: woxtu Date: Fri, 23 Dec 2022 20:36:27 +0900 Subject: [PATCH 703/733] Remove a redundant defer --- .../Attachment/AttachmentViewModel.swift | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift index e420d9ad1..3ff97769e 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift @@ -133,38 +133,36 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable .receive(on: DispatchQueue.main) .assign(to: &$thumbnail) - defer { - let uploadTask = Task { @MainActor in - do { - var output = try await load(input: input) - - switch output { - case .image(let data, _): - self.output = output - self.update(uploadState: .compressing) - let compressedOutput = try await compressImage(data: data, sizeLimit: sizeLimit) - output = compressedOutput - case .video(let fileURL, let mimeType): - self.output = output - self.update(uploadState: .compressing) - let compressedFileURL = try await compressVideo(url: fileURL) - output = .video(compressedFileURL, mimeType: mimeType) - try? FileManager.default.removeItem(at: fileURL) // remove old file - } - - self.outputSizeInByte = output.asAttachment.sizeInByte.flatMap { Int64($0) } ?? 0 + let uploadTask = Task { @MainActor in + do { + var output = try await load(input: input) + + switch output { + case .image(let data, _): self.output = output - - self.update(uploadState: .ready) - self.delegate?.attachmentViewModel(self, uploadStateValueDidChange: self.uploadState) - } catch { - self.error = error + self.update(uploadState: .compressing) + let compressedOutput = try await compressImage(data: data, sizeLimit: sizeLimit) + output = compressedOutput + case .video(let fileURL, let mimeType): + self.output = output + self.update(uploadState: .compressing) + let compressedFileURL = try await compressVideo(url: fileURL) + output = .video(compressedFileURL, mimeType: mimeType) + try? FileManager.default.removeItem(at: fileURL) // remove old file } - } // end Task - self.uploadTask = uploadTask - Task { - await uploadTask.value + + self.outputSizeInByte = output.asAttachment.sizeInByte.flatMap { Int64($0) } ?? 0 + self.output = output + + self.update(uploadState: .ready) + self.delegate?.attachmentViewModel(self, uploadStateValueDidChange: self.uploadState) + } catch { + self.error = error } + } // end Task + self.uploadTask = uploadTask + Task { + await uploadTask.value } } From b00d6c0d27f4449e6318c2a00658177da9d51746 Mon Sep 17 00:00:00 2001 From: woxtu Date: Fri, 23 Dec 2022 21:00:13 +0900 Subject: [PATCH 704/733] Replace a deprecated constant --- MastodonSDK/Sources/MastodonCore/Extension/NSItemProvider.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonCore/Extension/NSItemProvider.swift b/MastodonSDK/Sources/MastodonCore/Extension/NSItemProvider.swift index c6fbff4f5..c5b8d513c 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/NSItemProvider.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/NSItemProvider.swift @@ -65,7 +65,7 @@ extension NSItemProvider { } let data = NSMutableData() - guard let imageDestination = CGImageDestinationCreateWithData(data, kUTTypeJPEG, 1, nil) else { + guard let imageDestination = CGImageDestinationCreateWithData(data, UTType.jpeg.identifier as CFString, 1, nil) else { continuation.resume(with: .success(nil)) assertionFailure() return From 0faea45485693ae7f00c947f4f2100079ec8eb7c Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 10:27:07 -0500 Subject: [PATCH 705/733] Allow AltViewController text to scroll --- .../MediaPreview/AltViewController.swift | 19 +++++++++---------- .../MastodonExtension/UIEdgeInsets.swift | 3 +++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 305487397..16a9c078c 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -24,6 +24,11 @@ class AltViewController: UIViewController { @MainActor required dynamic init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func loadView() { + super.loadView() + view.translatesAutoresizingMaskIntoConstraints = false + } override func viewDidLoad() { super.viewDidLoad() @@ -38,22 +43,16 @@ class AltViewController: UIViewController { right: 0 ) label.font = .preferredFont(forTextStyle: .callout) - label.isScrollEnabled = false + label.isScrollEnabled = true label.backgroundColor = .clear label.isOpaque = false label.isEditable = false label.tintColor = .white label.text = alt - view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(label) - NSLayoutConstraint.activate( - NSLayoutConstraint.constraints(withVisualFormat: "V:|-[label]-|", metrics: nil, views: ["label": label]) - ) - NSLayoutConstraint.activate( - NSLayoutConstraint.constraints(withVisualFormat: "H:|-(8)-[label]-(8)-|", metrics: nil, views: ["label": label]) - ) + label.pinToParent(padding: UIEdgeInsets(horizontal: 8, vertical: 0)) NSLayoutConstraint.activate([ label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), ]) @@ -63,8 +62,8 @@ class AltViewController: UIViewController { super.viewDidLayoutSubviews() UIView.performWithoutAnimation { preferredContentSize = CGSize( - width: label.intrinsicContentSize.width + 16, - height: label.intrinsicContentSize.height + view.layoutMargins.top + view.layoutMargins.bottom + width: label.contentSize.width + 16, + height: label.contentSize.height + view.layoutMargins.top + view.layoutMargins.bottom ) } } diff --git a/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift b/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift index 8436ff5d2..ea69bcefc 100644 --- a/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift +++ b/MastodonSDK/Sources/MastodonExtension/UIEdgeInsets.swift @@ -8,6 +8,9 @@ import UIKit extension UIEdgeInsets { + public init(horizontal: CGFloat, vertical: CGFloat) { + self.init(top: vertical, left: horizontal, bottom: vertical, right: horizontal) + } public static func constant(_ offset: CGFloat) -> Self { UIEdgeInsets(top: offset, left: offset, bottom: offset, right: offset) } From 2a161886a1bb630c1724153f1460367badcd5aa3 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 10:57:53 -0500 Subject: [PATCH 706/733] Improve HUDButton contrast --- MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift index 566100bb6..07d70e74e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift @@ -12,18 +12,17 @@ public class HUDButton: UIView { public static let height: CGFloat = 30 let background: UIVisualEffectView = { - let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)) - backgroundView.alpha = 0.9 + let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThinMaterial)) backgroundView.layer.masksToBounds = true backgroundView.layer.cornerRadius = HUDButton.height * 0.5 return backgroundView }() - let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemUltraThinMaterial))) + let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemThinMaterial))) public let button: UIButton = { let button = HighlightDimmableButton() - button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) + button.expandEdgeInsets = .constant(-10) button.contentEdgeInsets = .constant(7) button.imageView?.tintColor = .label button.titleLabel?.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)) From b8b59674f305c19ef17d7d26960e7634368b1a96 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 11:14:04 -0500 Subject: [PATCH 707/733] Fix scroll insets, increase contrast --- Mastodon/Scene/MediaPreview/AltViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 16a9c078c..9a11d20f8 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -49,10 +49,13 @@ class AltViewController: UIViewController { label.isEditable = false label.tintColor = .white label.text = alt + label.textContainerInset = UIEdgeInsets(horizontal: 8, vertical: 16) + label.verticalScrollIndicatorInsets.bottom = 4 + view.backgroundColor = .systemBackground view.addSubview(label) - label.pinToParent(padding: UIEdgeInsets(horizontal: 8, vertical: 0)) + label.pinToParent() NSLayoutConstraint.activate([ label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), ]) From d0812f4275636b7609bbec3226c95d85c1e4099f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 11:31:53 -0500 Subject: [PATCH 708/733] Further improve HUDButton contrast --- MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift index 07d70e74e..26dda32d6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Button/HUDButton.swift @@ -12,13 +12,13 @@ public class HUDButton: UIView { public static let height: CGFloat = 30 let background: UIVisualEffectView = { - let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThinMaterial)) + let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) backgroundView.layer.masksToBounds = true backgroundView.layer.cornerRadius = HUDButton.height * 0.5 return backgroundView }() - let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemThinMaterial))) + let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .systemMaterial))) public let button: UIButton = { let button = HighlightDimmableButton() From 752d76c8be0b533f6340e29e22c762bee8d52ef3 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 12:08:46 -0500 Subject: [PATCH 709/733] fix sizing if the text view does not need to scroll --- .../Scene/MediaPreview/AltViewController.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 9a11d20f8..5fba21b1f 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -9,7 +9,14 @@ import SwiftUI class AltViewController: UIViewController { private var alt: String - let label = UITextView() + let label = { + if #available(iOS 16, *) { + // TODO: update code below to use TextKit 2 when dropping iOS 15 support + return UITextView(usingTextLayoutManager: false) + } else { + return UITextView() + } + }() init(alt: String, sourceView: UIView?) { self.alt = alt @@ -49,7 +56,8 @@ class AltViewController: UIViewController { label.isEditable = false label.tintColor = .white label.text = alt - label.textContainerInset = UIEdgeInsets(horizontal: 8, vertical: 16) + label.textContainerInset = UIEdgeInsets(top: 12, left: 8, bottom: 8, right: 8) + label.contentInsetAdjustmentBehavior = .always label.verticalScrollIndicatorInsets.bottom = 4 view.backgroundColor = .systemBackground @@ -64,9 +72,10 @@ class AltViewController: UIViewController { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() UIView.performWithoutAnimation { + let size = label.layoutManager.boundingRect(forGlyphRange: NSMakeRange(0, (label.textStorage.string as NSString).length), in: label.textContainer).size preferredContentSize = CGSize( - width: label.contentSize.width + 16, - height: label.contentSize.height + view.layoutMargins.top + view.layoutMargins.bottom + width: size.width + (8 + label.textContainer.lineFragmentPadding) * 2, + height: size.height + 12 + (label.textContainer.lineFragmentPadding * 2) ) } } From d553dd4f6292cd3ae217c9007de51bf7ce67dad1 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 23 Dec 2022 14:16:41 -0500 Subject: [PATCH 710/733] Resize text when Dynamic Type style updates --- Mastodon/Scene/MediaPreview/AltViewController.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 5fba21b1f..668771fac 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -79,6 +79,11 @@ class AltViewController: UIViewController { ) } } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + label.font = .preferredFont(forTextStyle: .callout) + } } // MARK: UIPopoverPresentationControllerDelegate From deb977707ac2ca6e8a0ccee2230abf07218b2ac1 Mon Sep 17 00:00:00 2001 From: Mary Date: Sun, 25 Dec 2022 12:04:59 +0100 Subject: [PATCH 711/733] Address comments --- .../Extension/CoreDataStack/Status+Property.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift index ca4fa9fc9..9e92e0d2c 100644 --- a/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift +++ b/MastodonSDK/Sources/MastodonCore/Extension/CoreDataStack/Status+Property.swift @@ -62,9 +62,9 @@ extension Mastodon.Entity.Status { let original = meta.original, let originalWidth = original.width, let originalHeight = original.height { - width = originalWidth; // audio has width/height - height = originalHeight; - durationMS = original.duration.flatMap { Int($0 * 1000) } + width = originalWidth // audio has width/height + height = originalHeight + durationMS = original.duration.map { Int($0 * 1000) } } else { // In case metadata field is missing, use default values. From c1f19d1f27c8af4e285148ccbd0c0ca82eee82ce Mon Sep 17 00:00:00 2001 From: Peter Minarik Date: Sun, 25 Dec 2022 16:56:46 +0100 Subject: [PATCH 712/733] chore: DRY setting up colors from theme --- .../Profile/Header/View/ProfileHeaderView.swift | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index ccc3dbe9f..c3ae089e7 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -242,14 +242,13 @@ final class ProfileHeaderView: UIView { extension ProfileHeaderView { private func _init() { - backgroundColor = ThemeService.shared.currentTheme.value.systemBackgroundColor - avatarButton.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor - ThemeService.shared.currentTheme + let currentTheme = ThemeService.shared.currentTheme + setColors(from: currentTheme.value) + + currentTheme .receive(on: DispatchQueue.main) .sink { [weak self] theme in - guard let self = self else { return } - self.backgroundColor = theme.systemBackgroundColor - self.avatarButton.backgroundColor = theme.secondarySystemBackgroundColor + self?.setColors(from: theme) } .store(in: &_disposeBag) @@ -455,6 +454,11 @@ extension ProfileHeaderView { updateLayoutMargins() } + + private func setColors(from theme: Theme) { + backgroundColor = theme.systemBackgroundColor + avatarButton.backgroundColor = theme.secondarySystemBackgroundColor + } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) From fd964c7b3ac20497683478c28ec72c28fd779b18 Mon Sep 17 00:00:00 2001 From: Peter Minarik Date: Sun, 25 Dec 2022 16:57:14 +0100 Subject: [PATCH 713/733] fix: set Avatar border color based on theme --- Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index c3ae089e7..5204cf567 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -28,7 +28,6 @@ final class ProfileHeaderView: UIView { static let avatarImageViewSize = CGSize(width: 98, height: 98) static let avatarImageViewCornerRadius: CGFloat = 25 - static let avatarImageViewBorderColor = UIColor.white static let avatarImageViewBorderWidth: CGFloat = 2 static let friendshipActionButtonSize = CGSize(width: 108, height: 34) static let bannerImageViewPlaceholderColor = UIColor.systemGray @@ -90,7 +89,6 @@ final class ProfileHeaderView: UIView { view.layer.masksToBounds = true view.layer.cornerRadius = ProfileHeaderView.avatarImageViewCornerRadius view.layer.cornerCurve = .continuous - view.layer.borderColor = ProfileHeaderView.avatarImageViewBorderColor.cgColor view.layer.borderWidth = ProfileHeaderView.avatarImageViewBorderWidth return view }() @@ -458,6 +456,7 @@ extension ProfileHeaderView { private func setColors(from theme: Theme) { backgroundColor = theme.systemBackgroundColor avatarButton.backgroundColor = theme.secondarySystemBackgroundColor + avatarImageViewBackgroundView.layer.borderColor = theme.systemBackgroundColor.cgColor } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { From 8beb74421617142d56a5c8f0e03a1784cd248fee Mon Sep 17 00:00:00 2001 From: Peter Minarik Date: Sun, 25 Dec 2022 16:57:32 +0100 Subject: [PATCH 714/733] chore: update lock podfile --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index cff1861dd..f0949d7ab 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -29,6 +29,6 @@ SPEC CHECKSUMS: SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: 9bca0a8bef019bda7253d8b5cdbce4c53a141398 +PODFILE CHECKSUM: 5b1dbf90a3e6fff01240ad0a2ceb2bc7f7bb4e36 COCOAPODS: 1.11.3 From f26f36a60bf386e9b0936d91363dfbbb152d41aa Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 26 Dec 2022 15:29:01 +0100 Subject: [PATCH 715/733] Slightly adjust code (#806) Renaming, remove iOS-checks. --- .../MediaPreview/AltViewController.swift | 62 +++++++++---------- .../MediaPreviewViewController.swift | 2 +- .../View/Content/MediaAltTextOverlay.swift | 2 - .../MastodonUI/View/Content/MediaView.swift | 37 ++++------- 4 files changed, 43 insertions(+), 60 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/AltViewController.swift b/Mastodon/Scene/MediaPreview/AltViewController.swift index 668771fac..05a3e5b09 100644 --- a/Mastodon/Scene/MediaPreview/AltViewController.swift +++ b/Mastodon/Scene/MediaPreview/AltViewController.swift @@ -8,18 +8,33 @@ import SwiftUI class AltViewController: UIViewController { - private var alt: String - let label = { + let textView = { + let textView: UITextView + if #available(iOS 16, *) { // TODO: update code below to use TextKit 2 when dropping iOS 15 support - return UITextView(usingTextLayoutManager: false) + textView = UITextView(usingTextLayoutManager: false) } else { - return UITextView() + textView = UITextView() } + + textView.textContainer.maximumNumberOfLines = 0 + textView.textContainer.lineBreakMode = .byWordWrapping + textView.font = .preferredFont(forTextStyle: .callout) + textView.isScrollEnabled = true + textView.backgroundColor = .clear + textView.isOpaque = false + textView.isEditable = false + textView.tintColor = .white + textView.textContainerInset = UIEdgeInsets(top: 12, left: 8, bottom: 8, right: 8) + textView.contentInsetAdjustmentBehavior = .always + textView.verticalScrollIndicatorInsets.bottom = 4 + + return textView }() init(alt: String, sourceView: UIView?) { - self.alt = alt + textView.text = alt super.init(nibName: nil, bundle: nil) self.modalPresentationStyle = .popover self.popoverPresentationController?.delegate = self @@ -40,49 +55,32 @@ class AltViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - label.translatesAutoresizingMaskIntoConstraints = false - label.textContainer.maximumNumberOfLines = 0 - label.textContainer.lineBreakMode = .byWordWrapping - label.textContainerInset = UIEdgeInsets( - top: 8, - left: 0, - bottom: -label.textContainer.lineFragmentPadding, - right: 0 - ) - label.font = .preferredFont(forTextStyle: .callout) - label.isScrollEnabled = true - label.backgroundColor = .clear - label.isOpaque = false - label.isEditable = false - label.tintColor = .white - label.text = alt - label.textContainerInset = UIEdgeInsets(top: 12, left: 8, bottom: 8, right: 8) - label.contentInsetAdjustmentBehavior = .always - label.verticalScrollIndicatorInsets.bottom = 4 - + textView.translatesAutoresizingMaskIntoConstraints = false view.backgroundColor = .systemBackground - view.addSubview(label) + view.addSubview(textView) - label.pinToParent() + textView.pinToParent() NSLayoutConstraint.activate([ - label.widthAnchor.constraint(lessThanOrEqualToConstant: 400), + textView.widthAnchor.constraint(lessThanOrEqualToConstant: 400), ]) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() UIView.performWithoutAnimation { - let size = label.layoutManager.boundingRect(forGlyphRange: NSMakeRange(0, (label.textStorage.string as NSString).length), in: label.textContainer).size + + let size = textView.layoutManager.boundingRect(forGlyphRange: NSMakeRange(0, (textView.textStorage.string as NSString).length), in: textView.textContainer).size + preferredContentSize = CGSize( - width: size.width + (8 + label.textContainer.lineFragmentPadding) * 2, - height: size.height + 12 + (label.textContainer.lineFragmentPadding * 2) + width: size.width + (8 + textView.textContainer.lineFragmentPadding) * 2, + height: size.height + 12 + (textView.textContainer.lineFragmentPadding) * 2 ) } } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) - label.font = .preferredFont(forTextStyle: .callout) + textView.font = .preferredFont(forTextStyle: .callout) } } diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index 1200c7d85..ede0be296 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -181,9 +181,9 @@ extension MediaPreviewViewController { @objc private func altButtonPressed(_ sender: UIButton) { guard let alt = viewModel.altText else { return } + present(AltViewController(alt: alt, sourceView: sender), animated: true) } - } // MARK: - MediaPreviewingViewController diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift index fec17f1ee..a625be292 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaAltTextOverlay.swift @@ -7,7 +7,6 @@ import SwiftUI -@available(iOS 15.0, *) struct MediaAltTextOverlay: View { var altDescription: String? @@ -69,7 +68,6 @@ struct MediaAltTextOverlay: View { } } -@available(iOS 15.0, *) struct MediaAltTextOverlay_Previews: PreviewProvider { static var previews: some View { MediaAltTextOverlay(altDescription: "Hello, world!") diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index a140d9737..ba5a09572 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -73,20 +73,12 @@ public final class MediaView: UIView { return label }() - let _altViewController: UIViewController! = { - if #available(iOS 15.0, *) { - let vc = UIHostingController(rootView: MediaAltTextOverlay()) - vc.view.backgroundColor = .clear - return vc - } else { - return nil - } + let altViewController: UIHostingController = { + let vc = UIHostingController(rootView: MediaAltTextOverlay()) + vc.view.backgroundColor = .clear + return vc }() - @available(iOS 15.0, *) - var altViewController: UIHostingController { - _altViewController as! UIHostingController - } - + public override init(frame: CGRect) { super.init(frame: frame) _init() @@ -228,9 +220,8 @@ extension MediaView { } else { accessibilityLabel = altDescription } - if #available(iOS 15.0, *) { - altViewController.rootView.altDescription = altDescription - } + + altViewController.rootView.altDescription = altDescription } private func layoutBlurhash() { @@ -262,11 +253,9 @@ extension MediaView { } private func layoutAlt() { - if #available(iOS 15.0, *) { - altViewController.view.translatesAutoresizingMaskIntoConstraints = false - container.addSubview(altViewController.view) - altViewController.view.pinToParent() - } + altViewController.view.translatesAutoresizingMaskIntoConstraints = false + container.addSubview(altViewController.view) + altViewController.view.pinToParent() } public func prepareForReuse() { @@ -304,10 +293,8 @@ extension MediaView { container.removeFromSuperview() container.removeConstraints(container.constraints) - if #available(iOS 15.0, *) { - altViewController.rootView.altDescription = nil - } - + altViewController.rootView.altDescription = nil + // reset configuration configuration = nil } From 33be360979486bb7efafd575da4a4e7e858ac844 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 26 Dec 2022 20:07:19 +0100 Subject: [PATCH 716/733] Set color of playback-button White on light gray doesn't look good, now it's at least visible. --- .../MastodonUI/View/Content/MediaView.swift | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index ba5a09572..d543e64c8 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -12,6 +12,7 @@ import Combine import AlamofireImage import SwiftUI import MastodonLocalization +import MastodonAsset public final class MediaView: UIView { @@ -49,11 +50,20 @@ public final class MediaView: UIView { return playerViewController }() private var playerLooper: AVPlayerLooper? - private(set) lazy var playbackImageView: UIImageView = { + + private(set) lazy var playbackImageView: UIView = { + let wrapper = UIView() + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false imageView.image = UIImage(systemName: "play.circle.fill") - imageView.tintColor = .white - return imageView + imageView.tintColor = Asset.Colors.Label.primary.color + wrapper.addSubview(imageView) + imageView.pinToParent(padding: .init(top: 8, left: 8, bottom: 8, right: 8)) + wrapper.backgroundColor = Asset.Theme.Mastodon.systemBackground.color.withAlphaComponent(0.8) + wrapper.applyCornerRadius(radius: 8) + + return wrapper }() private(set) lazy var indicatorBlurEffectView: UIVisualEffectView = { From b65bf9155b08e3eea24461282134c4a7ee9cb784 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 26 Dec 2022 20:08:08 +0100 Subject: [PATCH 717/733] Somehow swiftgen didn't run once? --- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index e4bc9b418..b974ba7bc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -728,8 +728,8 @@ public enum L10n { public enum Accessibility { /// Tap to scroll to top and tap again to previous location public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint", fallback: "Tap to scroll to top and tap again to previous location") - /// Logo Button - public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Logo Button") + /// Mastodon + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon") } } } From 6c260f942f3f8ef0b9f5965fed55d05cf8814127 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 28 Dec 2022 11:52:44 +0100 Subject: [PATCH 718/733] feat: Implement abbreviated status counts --- .../Sources/MastodonExtension/Int.swift | 31 +++++++++++ .../View/Control/ActionToolbarContainer.swift | 3 +- .../MastodonExtensionTests/IntTests.swift | 53 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 MastodonSDK/Sources/MastodonExtension/Int.swift create mode 100644 MastodonSDK/Tests/MastodonExtensionTests/IntTests.swift diff --git a/MastodonSDK/Sources/MastodonExtension/Int.swift b/MastodonSDK/Sources/MastodonExtension/Int.swift new file mode 100644 index 000000000..e9c5ceb1e --- /dev/null +++ b/MastodonSDK/Sources/MastodonExtension/Int.swift @@ -0,0 +1,31 @@ +// +// Int.swift +// +// +// Created by Marcus Kida on 28.12.22. +// + +import Foundation + +public extension Int { + func asAbbreviatedCountString() -> String { + switch self { + case ..<1_000: + return String(format: "%d", locale: Locale.current, self) + case 1_000 ..< 999_999: + return String(format: "%.1fK", locale: Locale.current, Double(self) / 1_000) + .sanitizedAbbreviatedCountString(for: "K") + default: + return String(format: "%.1fM", locale: Locale.current, Double(self) / 1_000_000) + .sanitizedAbbreviatedCountString(for: "M") + } + } +} + +fileprivate extension String { + func sanitizedAbbreviatedCountString(for value: String) -> String { + [".0", ",0", "٫٠"].reduce(self) { res, acc in + return res.replacingOccurrences(of: "\(acc)\(value)", with: value) + } + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift index 73695b782..ccb59157a 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift @@ -9,6 +9,7 @@ import os.log import UIKit import MastodonAsset import MastodonLocalization +import MastodonExtension public protocol ActionToolbarContainerDelegate: AnyObject { func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) @@ -283,7 +284,7 @@ extension ActionToolbarContainer { extension ActionToolbarContainer { private static func title(from number: Int?) -> String { guard let number = number, number > 0 else { return "" } - return String(number) + return number.asAbbreviatedCountString() } } diff --git a/MastodonSDK/Tests/MastodonExtensionTests/IntTests.swift b/MastodonSDK/Tests/MastodonExtensionTests/IntTests.swift new file mode 100644 index 000000000..ec0d045b2 --- /dev/null +++ b/MastodonSDK/Tests/MastodonExtensionTests/IntTests.swift @@ -0,0 +1,53 @@ +// +// IntTests.swift +// +// +// Created by Marcus Kida on 28.12.22. +// + +import XCTest +@testable import MastodonSDK + +class IntFriendlyCountTests: XCTestCase { + func testFriendlyCount_for_1000() { + let input = 1_000 + let expectedOutput = "1K" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } + + func testFriendlyCount_for_1200() { + let input = 1_200 + let expectedOutput = "1.2K" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } + + func testFriendlyCount_for_50000() { + let input = 50_000 + let expectedOutput = "50K" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } + + func testFriendlyCount_for_70666() { + let input = 70_666 + let expectedOutput = "70.7K" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } + + func testFriendlyCount_for_1M() { + let input = 1_000_000 + let expectedOutput = "1M" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } + + func testFriendlyCount_for_1dot5M() { + let input = 1_499_000 + let expectedOutput = "1.5M" + + XCTAssertEqual(expectedOutput, input.asAbbreviatedCountString()) + } +} From d5d90808150a50051876aab191031de2ad92af12 Mon Sep 17 00:00:00 2001 From: woxtu Date: Thu, 29 Dec 2022 00:47:53 +0900 Subject: [PATCH 719/733] Replace deprecated properties --- MastodonSDK/Sources/CoreDataStack/Extension/UIFont.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MastodonSDK/Sources/CoreDataStack/Extension/UIFont.swift b/MastodonSDK/Sources/CoreDataStack/Extension/UIFont.swift index a1a97a112..97fb2f397 100644 --- a/MastodonSDK/Sources/CoreDataStack/Extension/UIFont.swift +++ b/MastodonSDK/Sources/CoreDataStack/Extension/UIFont.swift @@ -22,9 +22,9 @@ extension UIFont { let fontDescription = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle).addingAttributes([ UIFontDescriptor.AttributeName.featureSettings: [ [ - UIFontDescriptor.FeatureKey.featureIdentifier: + UIFontDescriptor.FeatureKey.type: kNumberSpacingType, - UIFontDescriptor.FeatureKey.typeIdentifier: + UIFontDescriptor.FeatureKey.selector: kMonospacedNumbersSelector ] ] From 66b6bcd0ef015a59d72d832e8ad7939ce6f19fa9 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 29 Dec 2022 07:51:12 +0100 Subject: [PATCH 720/733] chore(onboarding): Replace parseUsersCount --- .../Diffable/Onboarding/PickServerSection.swift | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Mastodon/Diffable/Onboarding/PickServerSection.swift b/Mastodon/Diffable/Onboarding/PickServerSection.swift index ef7ca5972..1af5b23c6 100644 --- a/Mastodon/Diffable/Onboarding/PickServerSection.swift +++ b/Mastodon/Diffable/Onboarding/PickServerSection.swift @@ -77,7 +77,7 @@ extension PickServerSection { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineHeightMultiple = 1.12 let valueAttributedString = NSAttributedString( - string: parseUsersCount(server.totalUsers), + string: server.totalUsers.asAbbreviatedCountString(), attributes: [ .paragraphStyle: paragraphStyle ] @@ -125,17 +125,6 @@ extension PickServerSection { } .store(in: &cell.disposeBag) } - - private static func parseUsersCount(_ usersCount: Int) -> String { - switch usersCount { - case 0..<1000: - return "\(usersCount)" - default: - let usersCountInThousand = Float(usersCount) / 1000.0 - return String(format: "%.1fK", usersCountInThousand) - } - } - } extension PickServerSection { From 6d80df1279a1cab677a8e09e5468f4a92dade832 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Sat, 31 Dec 2022 02:22:00 +0100 Subject: [PATCH 721/733] fix: Poll percentages were wrong due to wrong count being used (votes vs voters) (#834) --- .../Share/View/Content/PollOptionView+Configuration.swift | 8 ++++---- .../View/Content/PollOptionView+ViewModel.swift | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/Share/View/Content/PollOptionView+Configuration.swift b/Mastodon/Scene/Share/View/Content/PollOptionView+Configuration.swift index 334c9ce15..cbc7c61f8 100644 --- a/Mastodon/Scene/Share/View/Content/PollOptionView+Configuration.swift +++ b/Mastodon/Scene/Share/View/Content/PollOptionView+Configuration.swift @@ -33,12 +33,12 @@ extension PollOptionView { .store(in: &disposeBag) // percentage Publishers.CombineLatest( - option.poll.publisher(for: \.votesCount), + option.poll.publisher(for: \.votersCount), option.publisher(for: \.votesCount) ) - .map { pollVotesCount, optionVotesCount -> Double? in - guard pollVotesCount > 0, optionVotesCount >= 0 else { return 0 } - return Double(optionVotesCount) / Double(pollVotesCount) + .map { pollVotersCount, optionVotesCount -> Double? in + guard pollVotersCount > 0, optionVotesCount >= 0 else { return 0 } + return Double(optionVotesCount) / Double(pollVotersCount) } .assign(to: \.percentage, on: viewModel) .store(in: &disposeBag) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/PollOptionView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/PollOptionView+ViewModel.swift index a91f57dc2..e3e34d1cb 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/PollOptionView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/PollOptionView+ViewModel.swift @@ -175,7 +175,7 @@ extension PollOptionView.ViewModel { view.voteProgressStripView.setProgress(0.0, animated: false) case .reveal(let voted, let percentage, let animating): view.optionPercentageLabel.isHidden = false - view.optionPercentageLabel.text = String(Int(100 * percentage)) + "%" + view.optionPercentageLabel.text = String(Int(round(100 * percentage))) + "%" view.voteProgressStripView.isHidden = false view.voteProgressStripView.tintColor = voted ? self.primaryStripProgressViewTintColor : self.secondaryStripProgressViewTintColor view.voteProgressStripView.setProgress(CGFloat(percentage), animated: animating) From fbc4c98e7d5d987f4da23d3db47878e8390c08ef Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sat, 31 Dec 2022 08:36:39 -0500 Subject: [PATCH 722/733] Force view controllers into portrait orientation where needed --- Mastodon.xcodeproj/project.pbxproj | 8 ++++++++ .../Extension/UIInterfaceOrientationMask.swift | 14 ++++++++++++++ Mastodon/Helper/PortraitAlertController.swift | 14 ++++++++++++++ Mastodon/Scene/Account/AccountViewController.swift | 3 +++ Mastodon/Scene/Compose/ComposeViewController.swift | 2 +- .../Share/OnboardingNavigationController.swift | 5 ++--- .../Scene/Root/MainTab/MainTabBarController.swift | 2 +- Mastodon/Scene/Root/RootSplitViewController.swift | 2 +- 8 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Mastodon/Extension/UIInterfaceOrientationMask.swift create mode 100644 Mastodon/Helper/PortraitAlertController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 3f70434b6..db397ba80 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -101,6 +101,8 @@ 62FD27D12893707600B205C5 /* BookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D02893707600B205C5 /* BookmarkViewController.swift */; }; 62FD27D32893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D22893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift */; }; 62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; }; + 855149C8295F1C5F00943D96 /* UIInterfaceOrientationMask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */; }; + 855149CA29606D6400943D96 /* PortraitAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C929606D6400943D96 /* PortraitAlertController.swift */; }; 85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; }; 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; 85BC11B32932414900E191CD /* AltViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltViewController.swift */; }; @@ -618,6 +620,8 @@ 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.profile.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.profile.xcconfig"; sourceTree = ""; }; 7CEFFAE9AF9284B13C0A758D /* Pods-MastodonTests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - debug.xcconfig"; sourceTree = ""; }; 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; + 855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterfaceOrientationMask.swift; sourceTree = ""; }; + 855149C929606D6400943D96 /* PortraitAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortraitAlertController.swift; sourceTree = ""; }; 85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = ""; }; 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = ""; }; 85BC11B22932414900E191CD /* AltViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltViewController.swift; sourceTree = ""; }; @@ -2274,6 +2278,7 @@ 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */, DBCC3B2F261440A50045B23D /* UITabBarController.swift */, 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */, + 855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */, ); path = Extension; sourceTree = ""; @@ -2543,6 +2548,7 @@ DBF3B7402733EB9400E21627 /* MastodonLocalCode.swift */, 85904C01293BC0EB0011C817 /* ImageProvider.swift */, 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */, + 855149C929606D6400943D96 /* PortraitAlertController.swift */, ); path = Helper; sourceTree = ""; @@ -3185,6 +3191,7 @@ DB1E347825F519300079D7DF /* PickServerItem.swift in Sources */, DB336F3F278E668C0031E64B /* StatusTableViewCell+ViewModel.swift in Sources */, DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */, + 855149C8295F1C5F00943D96 /* UIInterfaceOrientationMask.swift in Sources */, DBA5A53126F08EF000CACBAA /* DragIndicatorView.swift in Sources */, DB1FD45A25F27898004CFCFC /* CategoryPickerItem.swift in Sources */, DB6180F626391D580018D199 /* MediaPreviewableViewController.swift in Sources */, @@ -3529,6 +3536,7 @@ DBEFCD7D282A2A3B00C0ABEA /* ReportServerRulesViewController.swift in Sources */, DBB525362611ECEB002F1F29 /* UserTimelineViewController.swift in Sources */, DB98EB4927B0F0CD0082E365 /* ReportStatusTableViewCell.swift in Sources */, + 855149CA29606D6400943D96 /* PortraitAlertController.swift in Sources */, DBF3B7412733EB9400E21627 /* MastodonLocalCode.swift in Sources */, DB98EB6527B216500082E365 /* ReportResultViewModel.swift in Sources */, DB4F096A269EDAD200D62E92 /* SearchResultViewModel+State.swift in Sources */, diff --git a/Mastodon/Extension/UIInterfaceOrientationMask.swift b/Mastodon/Extension/UIInterfaceOrientationMask.swift new file mode 100644 index 000000000..2bc93fe85 --- /dev/null +++ b/Mastodon/Extension/UIInterfaceOrientationMask.swift @@ -0,0 +1,14 @@ +// +// UIInterfaceOrientationMask.swift +// Mastodon +// +// Created by Jed Fox on 2022-12-30. +// + +import UIKit + +extension UIInterfaceOrientationMask { + public static var portraitOnPhone: Self { + return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all + } +} diff --git a/Mastodon/Helper/PortraitAlertController.swift b/Mastodon/Helper/PortraitAlertController.swift new file mode 100644 index 000000000..afb93464a --- /dev/null +++ b/Mastodon/Helper/PortraitAlertController.swift @@ -0,0 +1,14 @@ +// +// PortraitAlertController.swift +// Mastodon +// +// Created by Jed Fox on 2022-12-31. +// + +import UIKit + +class PortraitAlertController: UIAlertController { + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portraitOnPhone + } +} diff --git a/Mastodon/Scene/Account/AccountViewController.swift b/Mastodon/Scene/Account/AccountViewController.swift index 7a0e529cc..75ea91fd6 100644 --- a/Mastodon/Scene/Account/AccountViewController.swift +++ b/Mastodon/Scene/Account/AccountViewController.swift @@ -49,6 +49,9 @@ final class AccountListViewController: UIViewController, NeedsDependency { return tableView }() + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portraitOnPhone + } } // MARK: - PanModalPresentable diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift index 9f287dbf8..fa5a1ef37 100644 --- a/Mastodon/Scene/Compose/ComposeViewController.swift +++ b/Mastodon/Scene/Compose/ComposeViewController.swift @@ -129,7 +129,7 @@ extension ComposeViewController { extension ComposeViewController { private func showDismissConfirmAlertController() { - let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + let alertController = PortraitAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let discardAction = UIAlertAction(title: L10n.Common.Controls.Actions.discard, style: .destructive) { [weak self] _ in guard let self = self else { return } self.dismiss(animated: true, completion: nil) diff --git a/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift b/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift index ac2e5b171..69108feb0 100644 --- a/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift +++ b/Mastodon/Scene/Onboarding/Share/OnboardingNavigationController.swift @@ -25,9 +25,8 @@ extension OnboardingNavigationController { updateBorderViewDisplay() } - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + .portraitOnPhone } } diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 00769e9f9..bf4d6beb1 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -370,7 +370,7 @@ extension MainTabBarController { } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { - return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all + .portraitOnPhone } } diff --git a/Mastodon/Scene/Root/RootSplitViewController.swift b/Mastodon/Scene/Root/RootSplitViewController.swift index 5332140db..c4caefd5f 100644 --- a/Mastodon/Scene/Root/RootSplitViewController.swift +++ b/Mastodon/Scene/Root/RootSplitViewController.swift @@ -114,7 +114,7 @@ extension RootSplitViewController { } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { - return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all + .portraitOnPhone } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { From f71c4964f53ed6143798885aaadecc2d1ae0fce3 Mon Sep 17 00:00:00 2001 From: jinsu kim Date: Sun, 1 Jan 2023 01:00:00 -0800 Subject: [PATCH 723/733] UI update should be invoked on the main thread --- .../Profile/RemoteProfileViewModel.swift | 64 ++++++++++--------- .../ThreadViewModel+LoadThreadState.swift | 5 +- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift index 1e1388c95..78575e5e4 100644 --- a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift +++ b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift @@ -17,38 +17,42 @@ final class RemoteProfileViewModel: ProfileViewModel { init(context: AppContext, authContext: AuthContext, userID: Mastodon.Entity.Account.ID) { super.init(context: context, authContext: authContext, optionalMastodonUser: nil) - let domain = authContext.mastodonAuthenticationBox.domain - let authorization = authContext.mastodonAuthenticationBox.userAuthorization - Just(userID) - .asyncMap { userID in - try await context.apiService.accountInfo( - domain: domain, - userID: userID, - authorization: authorization - ) - } - .retry(3) - .sink { completion in - switch completion { - case .failure(let error): - // TODO: handle error - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription) - case .finished: - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID) + Task { @MainActor in + let domain = authContext.mastodonAuthenticationBox.domain + let authorization = authContext.mastodonAuthenticationBox.userAuthorization + Just(userID) + .asyncMap { userID in + try await context.apiService.accountInfo( + domain: domain, + userID: userID, + authorization: authorization + ) } - } receiveValue: { [weak self] response in - guard let self = self else { return } - let managedObjectContext = context.managedObjectContext - let request = MastodonUser.sortedFetchRequest - request.fetchLimit = 1 - request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id) - guard let mastodonUser = managedObjectContext.safeFetch(request).first else { - assertionFailure() - return + .retry(3) + .sink { completion in + switch completion { + case .failure(let error): + // TODO: handle error + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription) + case .finished: + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID) + } + } receiveValue: { [weak self] response in + guard let self = self else { return } + let managedObjectContext = context.managedObjectContext + let request = MastodonUser.sortedFetchRequest + request.fetchLimit = 1 + request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id) + guard let mastodonUser = managedObjectContext.safeFetch(request).first else { + assertionFailure() + return + } + DispatchQueue.main.async { + self.user = mastodonUser + } } - self.user = mastodonUser - } - .store(in: &disposeBag) + .store(in: &disposeBag) + } } init(context: AppContext, authContext: AuthContext, notificationID: Mastodon.Entity.Notification.ID) { diff --git a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift index 1c6c40190..96ea928db 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift @@ -73,11 +73,12 @@ extension ThreadViewModel.LoadThreadState { return } - Task { + Task { @MainActor in do { let response = try await viewModel.context.apiService.statusContext( statusID: threadContext.statusID, - authenticationBox: viewModel.authContext.mastodonAuthenticationBox + authenticationBox: viewModel.authContext.mastodonAuthenticationBox, + domain: threadContext.domain ) await enter(state: NoMore.self) From de962a0c098213f6167417b169ecf706162cd940 Mon Sep 17 00:00:00 2001 From: jinsu kim Date: Sun, 1 Jan 2023 01:01:01 -0800 Subject: [PATCH 724/733] Implement URL scheme --- Mastodon/Supporting Files/SceneDelegate.swift | 106 +++++++++++++++--- .../Service/API/APIService+Account.swift | 41 +++++++ .../Service/API/APIService+Thread.swift | 80 ++++++++++++- 3 files changed, 210 insertions(+), 17 deletions(-) diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index e2f045a7b..82d4e06d7 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -12,6 +12,7 @@ import CoreDataStack import MastodonCore import MastodonExtension import MastodonUI +import MastodonSDK #if PROFILE import FPSIndicator @@ -67,6 +68,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { sceneCoordinator.setup() window.makeKeyAndVisible() + if let urlContext = connectionOptions.urlContexts.first { + handleUrl(context: urlContext) + } + #if SNAPSHOT // speedup animation // window.layer.speed = 999 @@ -187,21 +192,7 @@ extension SceneDelegate { coordinator.switchToTabBar(tab: .notifications) case "org.joinmastodon.app.new-post": - if coordinator?.tabBarController.topMost is ComposeViewController { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): composing…") - } else { - if let authContext = coordinator?.authContext { - let composeViewModel = ComposeViewModel( - context: AppContext.shared, - authContext: authContext, - destination: .topLevel - ) - _ = coordinator?.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): present compose scene") - } else { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): not authenticated") - } - } + showComposeViewController() case "org.joinmastodon.app.search": coordinator?.switchToTabBar(tab: .search) @@ -219,4 +210,89 @@ extension SceneDelegate { return true } + + func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + // Determine who sent the URL. + if let urlContext = URLContexts.first { + handleUrl(context: urlContext) + } + } + + private func showComposeViewController() { + if coordinator?.tabBarController.topMost is ComposeViewController { + logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): composing…") + } else { + if let authContext = coordinator?.authContext { + let composeViewModel = ComposeViewModel( + context: AppContext.shared, + authContext: authContext, + destination: .topLevel + ) + _ = coordinator?.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) + logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): present compose scene") + } else { + logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): not authenticated") + } + } + } + + private func handleUrl(context: UIOpenURLContext) { + let sendingAppID = context.options.sourceApplication + let url = context.url + + if !UIApplication.shared.canOpenURL(url) { return } + + print("source application = \(sendingAppID ?? "Unknown")") + print("url = \(url)") + + if let username = url.user { + guard let host = url.host else { return } + let components = url.pathComponents + if components.count == 3 && components[1] == "status" { + let statusId = components[2] + // View post from user + print("view status \(statusId)") + if let authContext = coordinator?.authContext { + Task { + guard let thread = try await AppContext.shared.apiService.fetchThread( + statusID: statusId, + domain: host, + authenticationBox: authContext.mastodonAuthenticationBox + ) else { return } + + let threadViewModel = CachedThreadViewModel(context: AppContext.shared, + authContext: authContext, + status: thread) + coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) + } + } + } else { + print("view profile \(username)@\(host)") + if let authContext = coordinator?.authContext { + Task { @MainActor in + guard let user = try await AppContext.shared.apiService.fetchUser( + username: username, + domain: host, + authenticationBox: authContext.mastodonAuthenticationBox + ) else { return } + + let profileViewModel = RemoteProfileViewModel(context: AppContext.shared, + authContext: authContext, + userID: user.id) + self.coordinator?.present( + scene: .profile(viewModel: profileViewModel), + from: nil, + transition: .show + ) + } + } + } + } else { + guard let action = url.host else { return } + if action == "post" { + print("make post") + showComposeViewController() + } + } + } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift index 8f89b4b76..d68984587 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift @@ -6,6 +6,7 @@ // import os.log +import CoreDataStack import Foundation import Combine import CommonOSLog @@ -199,3 +200,43 @@ extension APIService { return response } // end func } + +extension APIService { + public func fetchUser(username: String, domain: String, authenticationBox: MastodonAuthenticationBox) + async throws -> MastodonUser? { + let query = Mastodon.API.Account.AccountLookupQuery(acct: "\(username)@\(domain)") + let authorization = authenticationBox.userAuthorization + + let response = try await Mastodon.API.Account.lookupAccount( + session: session, + domain: authenticationBox.domain, + query: query, + authorization: authorization + ).singleOutput() + + // user + let managedObjectContext = self.backgroundManagedObjectContext + try await managedObjectContext.performChanges { + _ = Persistence.MastodonUser.createOrMerge( + in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: response.value, + cache: nil, + networkDate: response.networkDate + ) + ) + } + var result: MastodonUser? + try await managedObjectContext.perform { + result = Persistence.MastodonUser.fetch(in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: response.value, + cache: nil, + networkDate: response.networkDate + )) + } + return result + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift index ddd782856..902be16d2 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift @@ -16,9 +16,10 @@ extension APIService { public func statusContext( statusID: Mastodon.Entity.Status.ID, - authenticationBox: MastodonAuthenticationBox + authenticationBox: MastodonAuthenticationBox, + domain: String? = nil ) async throws -> Mastodon.Response.Content { - let domain = authenticationBox.domain + let domain = domain ?? authenticationBox.domain let authorization = authenticationBox.userAuthorization let response = try await Mastodon.API.Statuses.statusContext( @@ -51,4 +52,79 @@ extension APIService { return response } // end func + public func fetchThread( + statusID: Mastodon.Entity.Status.ID, + domain: String, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Status? { + let authorization = authenticationBox.userAuthorization + let managedObjectContext = self.backgroundManagedObjectContext + + let responseOne = try await Mastodon.API.Statuses.status( + session: session, + domain: domain, + statusID: statusID, + authorization: authorization + ).singleOutput() + + try await managedObjectContext.performChanges { + let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user + _ = Persistence.Status.createOrMerge( + in: managedObjectContext, + context: Persistence.Status.PersistContext( + domain: domain, + entity: responseOne.value, + me: me, + statusCache: nil, + userCache: nil, + networkDate: responseOne.networkDate + ) + ) + } + + let responseTwo = try await Mastodon.API.Statuses.statusContext( + session: session, + domain: domain, + statusID: statusID, + authorization: authorization + ).singleOutput() + + try await managedObjectContext.performChanges { + let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user + let value = responseTwo.value.ancestors + responseTwo.value.descendants + + for entity in value { + _ = Persistence.Status.createOrMerge( + in: managedObjectContext, + context: Persistence.Status.PersistContext( + domain: domain, + entity: entity, + me: me, + statusCache: nil, + userCache: nil, + networkDate: responseTwo.networkDate + ) + ) + } + } + + var result: Status? + try await managedObjectContext.perform { + let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user + + if let status = Persistence.Status.fetch(in: managedObjectContext, + context: Persistence.Status.PersistContext( + domain: domain, + entity: responseOne.value, + me: me, + statusCache: nil, + userCache: nil, + networkDate: responseOne.networkDate + )) { + result = status + } + } + + return result + } } From 5c82c04232f04aed848f96d8710beef49607d7a8 Mon Sep 17 00:00:00 2001 From: jinsu kim Date: Sun, 1 Jan 2023 15:55:54 -0800 Subject: [PATCH 725/733] Use authenticated domain for API calls. Modify URL scheme --- .../Profile/RemoteProfileViewModel.swift | 66 +++++++++---------- .../ThreadViewModel+LoadThreadState.swift | 3 +- Mastodon/Supporting Files/SceneDelegate.swift | 58 ++++++++-------- .../Service/API/APIService+Thread.swift | 7 +- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift index 78575e5e4..11a1bffcb 100644 --- a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift +++ b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift @@ -17,42 +17,40 @@ final class RemoteProfileViewModel: ProfileViewModel { init(context: AppContext, authContext: AuthContext, userID: Mastodon.Entity.Account.ID) { super.init(context: context, authContext: authContext, optionalMastodonUser: nil) - Task { @MainActor in - let domain = authContext.mastodonAuthenticationBox.domain - let authorization = authContext.mastodonAuthenticationBox.userAuthorization - Just(userID) - .asyncMap { userID in - try await context.apiService.accountInfo( - domain: domain, - userID: userID, - authorization: authorization - ) + let domain = authContext.mastodonAuthenticationBox.domain + let authorization = authContext.mastodonAuthenticationBox.userAuthorization + Just(userID) + .asyncMap { userID in + try await context.apiService.accountInfo( + domain: domain, + userID: userID, + authorization: authorization + ) + } + .retry(3) + .sink { completion in + switch completion { + case .failure(let error): + // TODO: handle error + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription) + case .finished: + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID) } - .retry(3) - .sink { completion in - switch completion { - case .failure(let error): - // TODO: handle error - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription) - case .finished: - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID) - } - } receiveValue: { [weak self] response in - guard let self = self else { return } - let managedObjectContext = context.managedObjectContext - let request = MastodonUser.sortedFetchRequest - request.fetchLimit = 1 - request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id) - guard let mastodonUser = managedObjectContext.safeFetch(request).first else { - assertionFailure() - return - } - DispatchQueue.main.async { - self.user = mastodonUser - } + } receiveValue: { [weak self] response in + guard let self = self else { return } + let managedObjectContext = context.managedObjectContext + let request = MastodonUser.sortedFetchRequest + request.fetchLimit = 1 + request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id) + guard let mastodonUser = managedObjectContext.safeFetch(request).first else { + assertionFailure() + return } - .store(in: &disposeBag) - } + DispatchQueue.main.async { + self.user = mastodonUser + } + } + .store(in: &disposeBag) } init(context: AppContext, authContext: AuthContext, notificationID: Mastodon.Entity.Notification.ID) { diff --git a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift index 96ea928db..87175cf55 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift @@ -77,8 +77,7 @@ extension ThreadViewModel.LoadThreadState { do { let response = try await viewModel.context.apiService.statusContext( statusID: threadContext.statusID, - authenticationBox: viewModel.authContext.mastodonAuthenticationBox, - domain: threadContext.domain + authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) await enter(state: NoMore.self) diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 82d4e06d7..2c6e3bf50 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -245,29 +245,17 @@ extension SceneDelegate { print("source application = \(sendingAppID ?? "Unknown")") print("url = \(url)") - if let username = url.user { - guard let host = url.host else { return } + switch url.host { + case "post": + showComposeViewController() + case "profile": let components = url.pathComponents - if components.count == 3 && components[1] == "status" { - let statusId = components[2] - // View post from user - print("view status \(statusId)") - if let authContext = coordinator?.authContext { - Task { - guard let thread = try await AppContext.shared.apiService.fetchThread( - statusID: statusId, - domain: host, - authenticationBox: authContext.mastodonAuthenticationBox - ) else { return } - - let threadViewModel = CachedThreadViewModel(context: AppContext.shared, - authContext: authContext, - status: thread) - coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) - } - } - } else { - print("view profile \(username)@\(host)") + if components.count == 2 && components[0] == "/" { + let addr = components[1] + let tokens = addr.components(separatedBy: "@") + if tokens.count != 2 { return } + let username = tokens[0] + let host = tokens[1] if let authContext = coordinator?.authContext { Task { @MainActor in guard let user = try await AppContext.shared.apiService.fetchUser( @@ -287,12 +275,28 @@ extension SceneDelegate { } } } - } else { - guard let action = url.host else { return } - if action == "post" { - print("make post") - showComposeViewController() + case "status": + let components = url.pathComponents + if components.count == 2 && components[0] == "/" { + let statusId = components[1] + // View post from user + print("view status \(statusId)") + if let authContext = coordinator?.authContext { + Task { + guard let thread = try await AppContext.shared.apiService.fetchThread( + statusID: statusId, + authenticationBox: authContext.mastodonAuthenticationBox + ) else { return } + + let threadViewModel = CachedThreadViewModel(context: AppContext.shared, + authContext: authContext, + status: thread) + coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) + } + } } + default: + return } } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift index 902be16d2..e2375e8dc 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift @@ -16,10 +16,9 @@ extension APIService { public func statusContext( statusID: Mastodon.Entity.Status.ID, - authenticationBox: MastodonAuthenticationBox, - domain: String? = nil + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content { - let domain = domain ?? authenticationBox.domain + let domain = authenticationBox.domain let authorization = authenticationBox.userAuthorization let response = try await Mastodon.API.Statuses.statusContext( @@ -54,9 +53,9 @@ extension APIService { public func fetchThread( statusID: Mastodon.Entity.Status.ID, - domain: String, authenticationBox: MastodonAuthenticationBox ) async throws -> Status? { + let domain = authenticationBox.domain let authorization = authenticationBox.userAuthorization let managedObjectContext = self.backgroundManagedObjectContext From 843eeed616817ab218e7dab644aa2f050bceb688 Mon Sep 17 00:00:00 2001 From: jinsu kim Date: Mon, 2 Jan 2023 00:26:15 -0800 Subject: [PATCH 726/733] Leave data loading to ThreadViewModel --- .../Service/API/APIService+Thread.swift | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift index e2375e8dc..d655a7e5c 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift @@ -81,31 +81,31 @@ extension APIService { ) } - let responseTwo = try await Mastodon.API.Statuses.statusContext( - session: session, - domain: domain, - statusID: statusID, - authorization: authorization - ).singleOutput() - - try await managedObjectContext.performChanges { - let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user - let value = responseTwo.value.ancestors + responseTwo.value.descendants - - for entity in value { - _ = Persistence.Status.createOrMerge( - in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: domain, - entity: entity, - me: me, - statusCache: nil, - userCache: nil, - networkDate: responseTwo.networkDate - ) - ) - } - } +// let responseTwo = try await Mastodon.API.Statuses.statusContext( +// session: session, +// domain: domain, +// statusID: statusID, +// authorization: authorization +// ).singleOutput() +// +// try await managedObjectContext.performChanges { +// let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user +// let value = responseTwo.value.ancestors + responseTwo.value.descendants +// +// for entity in value { +// _ = Persistence.Status.createOrMerge( +// in: managedObjectContext, +// context: Persistence.Status.PersistContext( +// domain: domain, +// entity: entity, +// me: me, +// statusCache: nil, +// userCache: nil, +// networkDate: responseTwo.networkDate +// ) +// ) +// } +// } var result: Status? try await managedObjectContext.perform { From b577d1ed77175981c56938ee01c1904be1326a96 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 4 Jan 2023 15:14:40 +0100 Subject: [PATCH 727/733] Revert .DS_Store --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c9c09fa6e..017cfd6fa 100644 --- a/.gitignore +++ b/.gitignore @@ -125,7 +125,7 @@ Localization/StringsConvertor/output .DS_Store env/**/** -!env/.env.DS_Store +!env/.env ## Ruby ### From 1fd509f4f91bb47eb31860cd5259c4cee3138b59 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 4 Jan 2023 15:35:40 +0100 Subject: [PATCH 728/733] Fix Share Extension Display Name --- ShareActionExtension/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShareActionExtension/Info.plist b/ShareActionExtension/Info.plist index 52924beed..f9993cc01 100644 --- a/ShareActionExtension/Info.plist +++ b/ShareActionExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - ShareActionExtension + Mastodon CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier From 2866721ca326dc4289d37f8f2a74cf86425efd00 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 4 Jan 2023 16:26:45 +0100 Subject: [PATCH 729/733] feat(profile): Implement tap to copy username --- .../View/ProfileHeaderView+ViewModel.swift | 4 ++- .../Header/View/ProfileHeaderView.swift | 35 +++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift index c5389958a..961a8269a 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView+ViewModel.swift @@ -150,7 +150,9 @@ extension ProfileHeaderView.ViewModel { // username $acct .map { acct in acct.flatMap { "@" + $0 } ?? " " } - .assign(to: \.text, on: view.usernameLabel) + .sink(receiveValue: { acct in + view.usernameButton.setTitle(acct, for: .normal) + }) .store(in: &disposeBag) // bio Publishers.CombineLatest4( diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index 5204cf567..2365c9320 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -172,15 +172,26 @@ final class ProfileHeaderView: UIView { textField.autocapitalizationType = .none return textField }() - - let usernameLabel: UILabel = { - let label = UILabel() - label.font = UIFontMetrics(forTextStyle: .callout).scaledFont(for: .systemFont(ofSize: 16, weight: .regular)) - label.adjustsFontSizeToFitWidth = true - label.minimumScaleFactor = 0.5 - label.textColor = Asset.Colors.Label.secondary.color - label.text = "@alice" - return label + + private lazy var usernameButtonMenu: UIMenu = { + UIMenu(children: [ + UIAction(title: L10n.Common.Controls.Actions.copy, handler: { [weak self] _ in + UIPasteboard.general.string = self?.usernameButton.title(for: .normal) + }) + ]) + }() + + lazy var usernameButton: UIButton = { + let button = UIButton() + button.setTitle("@alice", for: .normal) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .callout).scaledFont(for: .systemFont(ofSize: 16, weight: .regular)) + button.titleLabel?.adjustsFontSizeToFitWidth = true + button.titleLabel?.minimumScaleFactor = 0.5 + button.setTitleColor(Asset.Colors.Label.secondary.color, for: .normal) + button.menu = usernameButtonMenu + button.showsMenuAsPrimaryAction = true + button.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + return button }() let statusDashboardView = ProfileStatusDashboardView() @@ -417,7 +428,11 @@ extension ProfileHeaderView { // nameMetaText.textView.setContentHuggingPriority(, for: <#T##NSLayoutConstraint.Axis#>) nameContainerStackView.addArrangedSubview(displayNameStackView) - nameContainerStackView.addArrangedSubview(usernameLabel) + nameContainerStackView.addArrangedSubview(usernameButton) + + NSLayoutConstraint.activate([ + usernameButton.heightAnchor.constraint(equalToConstant: 20) + ]) authorContainer.addArrangedSubview(nameContainerStackView) authorContainer.addArrangedSubview(UIView()) From c56f1abd67643e6cf4311b6304c9a5209ea4f299 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 5 Jan 2023 11:47:43 +0100 Subject: [PATCH 730/733] chore(profile): Allow profile header username to grow in height --- Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index 2365c9320..3f4a83248 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -431,7 +431,7 @@ extension ProfileHeaderView { nameContainerStackView.addArrangedSubview(usernameButton) NSLayoutConstraint.activate([ - usernameButton.heightAnchor.constraint(equalToConstant: 20) + usernameButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 20) ]) authorContainer.addArrangedSubview(nameContainerStackView) From 74ea67181cf203d77789ebb8fe443a2e02e30211 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 5 Jan 2023 13:32:32 +0100 Subject: [PATCH 731/733] chore(profile): Add image to copy username action --- Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index 3f4a83248..322c3be01 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -175,7 +175,7 @@ final class ProfileHeaderView: UIView { private lazy var usernameButtonMenu: UIMenu = { UIMenu(children: [ - UIAction(title: L10n.Common.Controls.Actions.copy, handler: { [weak self] _ in + UIAction(title: L10n.Common.Controls.Actions.copy, image: UIImage(systemName: "doc.on.doc"), handler: { [weak self] _ in UIPasteboard.general.string = self?.usernameButton.title(for: .normal) }) ]) From a00cd6007672a1ecbcb36b362d5ff5c85bd2b695 Mon Sep 17 00:00:00 2001 From: jinsu kim Date: Thu, 5 Jan 2023 15:57:58 -0800 Subject: [PATCH 732/733] Remove duplicate function fetchUser(). --- .../Profile/RemoteProfileViewModel.swift | 42 +++++++++- Mastodon/Supporting Files/SceneDelegate.swift | 46 ++++------- .../Service/API/APIService+Account.swift | 31 ++++++++ .../Service/API/APIService+Thread.swift | 76 ------------------- 4 files changed, 84 insertions(+), 111 deletions(-) diff --git a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift index 11a1bffcb..89ff03660 100644 --- a/Mastodon/Scene/Profile/RemoteProfileViewModel.swift +++ b/Mastodon/Scene/Profile/RemoteProfileViewModel.swift @@ -28,6 +28,7 @@ final class RemoteProfileViewModel: ProfileViewModel { ) } .retry(3) + .receive(on: DispatchQueue.main) .sink { completion in switch completion { case .failure(let error): @@ -46,9 +47,7 @@ final class RemoteProfileViewModel: ProfileViewModel { assertionFailure() return } - DispatchQueue.main.async { - self.user = mastodonUser - } + self.user = mastodonUser } .store(in: &disposeBag) } @@ -91,4 +90,41 @@ final class RemoteProfileViewModel: ProfileViewModel { } // end Task } + init(context: AppContext, authContext: AuthContext, acct: String) { + super.init(context: context, authContext: authContext, optionalMastodonUser: nil) + + let domain = authContext.mastodonAuthenticationBox.domain + let authorization = authContext.mastodonAuthenticationBox.userAuthorization + Just(acct) + .asyncMap { acct in + try await context.apiService.accountSearch( + domain: domain, + query: .init(acct: acct), + authorization: authorization + ) + } + .retry(3) + .receive(on: DispatchQueue.main) + .sink { completion in + switch completion { + case .failure(let error): + // TODO: handle error + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, acct, error.localizedDescription) + case .finished: + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, acct) + } + } receiveValue: { [weak self] response in + guard let self = self else { return } + let managedObjectContext = context.managedObjectContext + let request = MastodonUser.sortedFetchRequest + request.fetchLimit = 1 + request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id) + guard let mastodonUser = managedObjectContext.safeFetch(request).first else { + assertionFailure() + return + } + self.user = mastodonUser + } + .store(in: &disposeBag) + } } diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index 2c6e3bf50..382755c77 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -252,27 +252,17 @@ extension SceneDelegate { let components = url.pathComponents if components.count == 2 && components[0] == "/" { let addr = components[1] - let tokens = addr.components(separatedBy: "@") - if tokens.count != 2 { return } - let username = tokens[0] - let host = tokens[1] if let authContext = coordinator?.authContext { - Task { @MainActor in - guard let user = try await AppContext.shared.apiService.fetchUser( - username: username, - domain: host, - authenticationBox: authContext.mastodonAuthenticationBox - ) else { return } - - let profileViewModel = RemoteProfileViewModel(context: AppContext.shared, - authContext: authContext, - userID: user.id) - self.coordinator?.present( - scene: .profile(viewModel: profileViewModel), - from: nil, - transition: .show - ) - } + let profileViewModel = RemoteProfileViewModel( + context: AppContext.shared, + authContext: authContext, + acct: components[1] + ) + self.coordinator?.present( + scene: .profile(viewModel: profileViewModel), + from: nil, + transition: .show + ) } } case "status": @@ -280,19 +270,11 @@ extension SceneDelegate { if components.count == 2 && components[0] == "/" { let statusId = components[1] // View post from user - print("view status \(statusId)") if let authContext = coordinator?.authContext { - Task { - guard let thread = try await AppContext.shared.apiService.fetchThread( - statusID: statusId, - authenticationBox: authContext.mastodonAuthenticationBox - ) else { return } - - let threadViewModel = CachedThreadViewModel(context: AppContext.shared, - authContext: authContext, - status: thread) - coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) - } + let threadViewModel = RemoteThreadViewModel(context: AppContext.shared, + authContext: authContext, + statusID: statusId) + coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) } } default: diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift index d68984587..34d398633 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift @@ -240,3 +240,34 @@ extension APIService { return result } } + +extension APIService { + public func accountSearch( + domain: String, + query: Mastodon.API.Account.AccountLookupQuery, + authorization: Mastodon.API.OAuth.Authorization + ) async throws -> Mastodon.Response.Content { + let response = try await Mastodon.API.Account.lookupAccount( + session: session, + domain: domain, + query: query, + authorization: authorization + ).singleOutput() + + // user + let managedObjectContext = self.backgroundManagedObjectContext + try await managedObjectContext.performChanges { + _ = Persistence.MastodonUser.createOrMerge( + in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: response.value, + cache: nil, + networkDate: response.networkDate + ) + ) + } + + return response + } +} diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift index d655a7e5c..f1b94376e 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Thread.swift @@ -50,80 +50,4 @@ extension APIService { return response } // end func - - public func fetchThread( - statusID: Mastodon.Entity.Status.ID, - authenticationBox: MastodonAuthenticationBox - ) async throws -> Status? { - let domain = authenticationBox.domain - let authorization = authenticationBox.userAuthorization - let managedObjectContext = self.backgroundManagedObjectContext - - let responseOne = try await Mastodon.API.Statuses.status( - session: session, - domain: domain, - statusID: statusID, - authorization: authorization - ).singleOutput() - - try await managedObjectContext.performChanges { - let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user - _ = Persistence.Status.createOrMerge( - in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: domain, - entity: responseOne.value, - me: me, - statusCache: nil, - userCache: nil, - networkDate: responseOne.networkDate - ) - ) - } - -// let responseTwo = try await Mastodon.API.Statuses.statusContext( -// session: session, -// domain: domain, -// statusID: statusID, -// authorization: authorization -// ).singleOutput() -// -// try await managedObjectContext.performChanges { -// let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user -// let value = responseTwo.value.ancestors + responseTwo.value.descendants -// -// for entity in value { -// _ = Persistence.Status.createOrMerge( -// in: managedObjectContext, -// context: Persistence.Status.PersistContext( -// domain: domain, -// entity: entity, -// me: me, -// statusCache: nil, -// userCache: nil, -// networkDate: responseTwo.networkDate -// ) -// ) -// } -// } - - var result: Status? - try await managedObjectContext.perform { - let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user - - if let status = Persistence.Status.fetch(in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: domain, - entity: responseOne.value, - me: me, - statusCache: nil, - userCache: nil, - networkDate: responseOne.networkDate - )) { - result = status - } - } - - return result - } } From 62f18c0204279050e226f031d8e3e7e8230b5887 Mon Sep 17 00:00:00 2001 From: woxtu Date: Fri, 6 Jan 2023 10:18:08 +0900 Subject: [PATCH 733/733] Enable to run the tests --- Mastodon.xcodeproj/project.pbxproj | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index db397ba80..42e7e56a4 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -107,6 +107,8 @@ 85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; }; 85BC11B32932414900E191CD /* AltViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltViewController.swift */; }; 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; }; + 9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; }; + 9E44C7222967AD17004B2A72 /* MastodonSDKDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; }; @@ -487,6 +489,17 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 9E44C7212967AD17004B2A72 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9E44C7222967AD17004B2A72 /* MastodonSDKDynamic in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; DB89BA0825C10FD0008580ED /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -1097,6 +1110,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */, 5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */, 5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */, ); @@ -2763,6 +2777,7 @@ DB427DE425BAA00100D1B89D /* Sources */, DB427DE525BAA00100D1B89D /* Frameworks */, DB427DE625BAA00100D1B89D /* Resources */, + 9E44C7212967AD17004B2A72 /* Embed Frameworks */, ); buildRules = ( ); @@ -2770,6 +2785,9 @@ DB427DEA25BAA00100D1B89D /* PBXTargetDependency */, ); name = MastodonTests; + packageProductDependencies = ( + 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */, + ); productName = MastodonTests; productReference = DB427DE825BAA00100D1B89D /* MastodonTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -4653,6 +4671,10 @@ isa = XCSwiftPackageProductDependency; productName = MastodonSDKDynamic; }; + 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */ = { + isa = XCSwiftPackageProductDependency; + productName = MastodonSDKDynamic; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = DB427DCA25BAA00100D1B89D /* Project object */;