diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
index c08f88276..c16279b6c 100644
--- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,12 +7,12 @@
AppShared.xcscheme_^#shared#^_
orderHint
- 32
+ 31
CoreDataStack.xcscheme_^#shared#^_
orderHint
- 31
+ 32
Mastodon - ASDK.xcscheme_^#shared#^_
@@ -77,7 +77,7 @@
MastodonIntent.xcscheme_^#shared#^_
orderHint
- 33
+ 30
MastodonIntents.xcscheme_^#shared#^_
@@ -97,7 +97,7 @@
ShareActionExtension.xcscheme_^#shared#^_
orderHint
- 30
+ 33
SuppressBuildableAutocreation
diff --git a/Mastodon/Diffiable/Section/Search/RecommendAccountSection.swift b/Mastodon/Diffiable/Section/Search/RecommendAccountSection.swift
index b894f818d..3d6cff19e 100644
--- a/Mastodon/Diffiable/Section/Search/RecommendAccountSection.swift
+++ b/Mastodon/Diffiable/Section/Search/RecommendAccountSection.swift
@@ -88,9 +88,7 @@ extension RecommendAccountSection {
withURL: URL(string: user.header)!,
placeholderImage: UIImage.placeholder(color: .systemFill),
imageTransition: .crossDissolve(0.2)
- ) { [weak cell] _ in
- // guard let cell = cell else { return }
- }
+ )
}
static func configureFollowButton(
diff --git a/Mastodon/Diffiable/Section/Status/NotificationSection.swift b/Mastodon/Diffiable/Section/Status/NotificationSection.swift
index b0afd7002..79e312299 100644
--- a/Mastodon/Diffiable/Section/Status/NotificationSection.swift
+++ b/Mastodon/Diffiable/Section/Status/NotificationSection.swift
@@ -79,13 +79,13 @@ extension NotificationSection {
let createAt = notification.createAt
let actionText = notification.notificationType.actionText
cell.actionLabel.text = actionText
- cell.timestampLabel.text = createAt.timeAgoSinceNow
+ cell.timestampLabel.text = createAt.localizedTimeAgoSinceNow
AppContext.shared.timestampUpdatePublisher
.receive(on: DispatchQueue.main)
.sink { [weak cell] _ in
guard let cell = cell else { return }
cell.actionLabel.text = actionText
- cell.timestampLabel.text = createAt.timeAgoSinceNow
+ cell.timestampLabel.text = createAt.localizedTimeAgoSinceNow
}
.store(in: &cell.disposeBag)
diff --git a/Mastodon/Diffiable/Section/Status/StatusSection.swift b/Mastodon/Diffiable/Section/Status/StatusSection.swift
index 92f39b215..6ec997845 100644
--- a/Mastodon/Diffiable/Section/Status/StatusSection.swift
+++ b/Mastodon/Diffiable/Section/Status/StatusSection.swift
@@ -953,11 +953,9 @@ extension StatusSection {
cell.statusView.pollCountdownSubscription = nil
cell.statusView.pollCountdownLabel.text = L10n.Common.Controls.Status.Poll.closed
} else if let expiresAt = poll.expiresAt {
- cell.statusView.pollCountdownLabel.text = L10n.Common.Controls.Status.Poll.timeLeft(expiresAt.shortTimeAgoSinceNow)
+ cell.statusView.pollCountdownLabel.text = expiresAt.localizedTimeLeft()
cell.statusView.pollCountdownSubscription = AppContext.shared.timestampUpdatePublisher
- .sink { _ in
- cell.statusView.pollCountdownLabel.text = L10n.Common.Controls.Status.Poll.timeLeft(expiresAt.shortTimeAgoSinceNow)
- }
+ .sink { _ in cell.statusView.pollCountdownLabel.text = expiresAt.localizedTimeLeft() }
} else {
cell.statusView.pollCountdownSubscription = nil
cell.statusView.pollCountdownLabel.text = "-"
@@ -1039,7 +1037,7 @@ extension StatusSection {
}()
cell.statusView.actionToolbarContainer.replyButton.setTitle(replyCountTitle, for: .normal)
cell.statusView.actionToolbarContainer.replyButton.accessibilityValue = status.repliesCount.flatMap {
- L10n.Common.Controls.Timeline.Accessibility.countReplies($0.intValue)
+ L10n.Plural.Count.reblog($0.intValue)
} ?? nil
// set reblog
let isReblogged = status.rebloggedBy.flatMap { $0.contains(where: { $0.id == requestUserID }) } ?? false
@@ -1052,7 +1050,7 @@ extension StatusSection {
cell.statusView.actionToolbarContainer.reblogButton.accessibilityLabel = isReblogged ? L10n.Common.Controls.Status.Actions.unreblog : L10n.Common.Controls.Status.Actions.reblog
cell.statusView.actionToolbarContainer.reblogButton.accessibilityValue = {
guard status.reblogsCount.intValue > 0 else { return nil }
- return L10n.Common.Controls.Timeline.Accessibility.countReblogs(status.reblogsCount.intValue)
+ return L10n.Plural.Count.reblog(status.reblogsCount.intValue)
}()
// disable reblog if needs (except self)
@@ -1077,7 +1075,7 @@ extension StatusSection {
cell.statusView.actionToolbarContainer.favoriteButton.accessibilityLabel = isLike ? L10n.Common.Controls.Status.Actions.unfavorite : L10n.Common.Controls.Status.Actions.favorite
cell.statusView.actionToolbarContainer.favoriteButton.accessibilityValue = {
guard status.favouritesCount.intValue > 0 else { return nil }
- return L10n.Common.Controls.Timeline.Accessibility.countReblogs(status.favouritesCount.intValue)
+ return L10n.Plural.Count.favorite(status.favouritesCount.intValue)
}()
Publishers.CombineLatest(
dependency.context.blockDomainService.blockedDomains.setFailureType(to: ManagedObjectObserver.Error.self),
diff --git a/Mastodon/Extension/Date.swift b/Mastodon/Extension/Date.swift
index 2d2ff6a99..86288c216 100644
--- a/Mastodon/Extension/Date.swift
+++ b/Mastodon/Extension/Date.swift
@@ -13,28 +13,56 @@ extension Date {
static let relativeTimestampFormatter: RelativeDateTimeFormatter = {
let formatter = RelativeDateTimeFormatter()
formatter.dateTimeStyle = .numeric
- formatter.unitsStyle = .abbreviated
+ formatter.unitsStyle = .full
return formatter
}()
var localizedSlowedTimeAgoSinceNow: String {
- return self.localizedSlowedTimeAgo(since: Date())
+ return self.localizedTimeAgo(since: Date(), isSlowed: true)
}
- func localizedSlowedTimeAgo(since date: Date) -> String {
+ var localizedTimeAgoSinceNow: String {
+ return self.localizedTimeAgo(since: Date(), isSlowed: false)
+ }
+
+ func localizedTimeAgo(since date: Date, isSlowed: Bool) -> String {
let earlierDate = date < self ? date : self
let latestDate = earlierDate == date ? self : date
- if earlierDate.timeIntervalSince(latestDate) >= -60 {
+ if isSlowed, earlierDate.timeIntervalSince(latestDate) >= -60 {
return L10n.Common.Controls.Timeline.Timestamp.now
} else {
return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate)
}
}
- func timeLeft() -> String {
- return ""
+}
+
+extension Date {
+
+ func localizedTimeLeft() -> String {
+ let date = Date()
+ let earlierDate = date < self ? date : self
+ let latestDate = earlierDate == date ? self : date
+
+ let components = Calendar.current.dateComponents([.year, .month, .day, .minute, .second], from: earlierDate, to: latestDate)
+
+ if components.year! > 0 {
+ return L10n.Date.Year.left(components.second!)
+ } else if components.month! > 0 {
+ return L10n.Date.Month.left(components.month!)
+ } else if components.day! > 0 {
+ return L10n.Date.Day.left(components.day!)
+ } else if components.hour! > 0 {
+ return L10n.Date.Hour.left(components.hour!)
+ } else if components.minute! > 0 {
+ return L10n.Date.Minute.left(components.minute!)
+ } else if components.second! > 0 {
+ return L10n.Date.Year.left(components.second!)
+ } else {
+ return ""
+ }
}
}
diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift
index 156680496..275c8e456 100644
--- a/Mastodon/Scene/Compose/ComposeViewController.swift
+++ b/Mastodon/Scene/Compose/ComposeViewController.swift
@@ -397,11 +397,11 @@ extension ComposeViewController {
case _ where count < 0:
self.composeToolbarView.characterCountLabel.font = .monospacedDigitSystemFont(ofSize: 24, weight: .bold)
self.composeToolbarView.characterCountLabel.textColor = Asset.Colors.danger.color
- self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitExceedsCount(abs(count))
+ self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitExceeds(abs(count))
default:
self.composeToolbarView.characterCountLabel.font = .monospacedDigitSystemFont(ofSize: 15, weight: .regular)
self.composeToolbarView.characterCountLabel.textColor = Asset.Colors.Label.secondary.color
- self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitRemainsCount(count)
+ self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(count)
}
}
.store(in: &disposeBag)
diff --git a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift b/Mastodon/Scene/Compose/View/ComposeToolbarView.swift
index c1cda22a6..99fe88ce7 100644
--- a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift
+++ b/Mastodon/Scene/Compose/View/ComposeToolbarView.swift
@@ -75,7 +75,7 @@ final class ComposeToolbarView: UIView {
label.font = .systemFont(ofSize: 15, weight: .regular)
label.text = "500"
label.textColor = Asset.Colors.Label.secondary.color
- label.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitRemainsCount(500)
+ label.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(500)
return label
}()
diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift
index 8d4a8b37f..9801d701a 100644
--- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift
+++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift
@@ -166,7 +166,7 @@ extension HashtagTimelineViewController {
.prefix(2)
.compactMap({ Int($0.accounts) })
.reduce(0, +)
- subtitle = L10n.Scene.Hashtag.prompt("\(peopleTalkingNumber)")
+ subtitle = L10n.Plural.peopleTalking(peopleTalkingNumber)
}
}
diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift
index fa54abf7b..f78079d2e 100644
--- a/Mastodon/Scene/Profile/ProfileViewController.swift
+++ b/Mastodon/Scene/Profile/ProfileViewController.swift
@@ -522,7 +522,7 @@ extension ProfileViewController {
let text = count.flatMap { MastodonMetricFormatter().string(from: $0) } ?? "-"
self.profileHeaderViewController.profileHeaderView.statusDashboardView.postDashboardMeterView.numberLabel.text = text
self.profileHeaderViewController.profileHeaderView.statusDashboardView.postDashboardMeterView.isAccessibilityElement = true
- self.profileHeaderViewController.profileHeaderView.statusDashboardView.postDashboardMeterView.accessibilityLabel = L10n.Scene.Profile.Dashboard.Accessibility.countPosts(count ?? 0)
+ self.profileHeaderViewController.profileHeaderView.statusDashboardView.postDashboardMeterView.accessibilityLabel = L10n.Plural.Count.post(count ?? 0)
}
.store(in: &disposeBag)
viewModel.followingCount
@@ -531,7 +531,7 @@ extension ProfileViewController {
let text = count.flatMap { MastodonMetricFormatter().string(from: $0) } ?? "-"
self.profileHeaderViewController.profileHeaderView.statusDashboardView.followingDashboardMeterView.numberLabel.text = text
self.profileHeaderViewController.profileHeaderView.statusDashboardView.followingDashboardMeterView.isAccessibilityElement = true
- self.profileHeaderViewController.profileHeaderView.statusDashboardView.followingDashboardMeterView.accessibilityLabel = L10n.Scene.Profile.Dashboard.Accessibility.countFollowing(count ?? 0)
+ self.profileHeaderViewController.profileHeaderView.statusDashboardView.followingDashboardMeterView.accessibilityLabel = L10n.Plural.Count.following(count ?? 0)
}
.store(in: &disposeBag)
viewModel.followersCount
@@ -540,7 +540,7 @@ extension ProfileViewController {
let text = count.flatMap { MastodonMetricFormatter().string(from: $0) } ?? "-"
self.profileHeaderViewController.profileHeaderView.statusDashboardView.followersDashboardMeterView.numberLabel.text = text
self.profileHeaderViewController.profileHeaderView.statusDashboardView.followersDashboardMeterView.isAccessibilityElement = true
- self.profileHeaderViewController.profileHeaderView.statusDashboardView.followersDashboardMeterView.accessibilityLabel = L10n.Scene.Profile.Dashboard.Accessibility.countFollowers(count ?? 0)
+ self.profileHeaderViewController.profileHeaderView.statusDashboardView.followersDashboardMeterView.accessibilityLabel = L10n.Plural.Count.follower(count ?? 0)
}
.store(in: &disposeBag)
viewModel.needsPagingEnabled
diff --git a/Mastodon/Scene/Search/Search/SearchViewModel.swift b/Mastodon/Scene/Search/Search/SearchViewModel.swift
index 1c2456091..feae75190 100644
--- a/Mastodon/Scene/Search/Search/SearchViewModel.swift
+++ b/Mastodon/Scene/Search/Search/SearchViewModel.swift
@@ -63,7 +63,7 @@ final class SearchViewModel: NSObject {
snapshot.appendSections([.main])
snapshot.appendItems(response.value, toSection: .main)
dataSource.apply(snapshot, animatingDifferences: false, completion: nil)
- case .failure(let error):
+ case .failure:
break
}
}
@@ -99,7 +99,7 @@ final class SearchViewModel: NSObject {
switch result {
case .success(let userIDs):
self.receiveAccounts(ids: userIDs)
- case .failure(let error):
+ case .failure:
break
}
}
diff --git a/Mastodon/Scene/Share/View/Content/StatusView.swift b/Mastodon/Scene/Share/View/Content/StatusView.swift
index 49452e1b4..664939fc4 100644
--- a/Mastodon/Scene/Share/View/Content/StatusView.swift
+++ b/Mastodon/Scene/Share/View/Content/StatusView.swift
@@ -168,7 +168,7 @@ final class StatusView: UIView {
let label = UILabel()
label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 12, weight: .regular))
label.textColor = Asset.Colors.Label.secondary.color
- label.text = L10n.Common.Controls.Status.Poll.timeLeft("6 hours")
+ label.text = "1 day left"
return label
}()
let pollVoteButton: UIButton = {
diff --git a/Mastodon/Scene/Thread/ThreadViewController.swift b/Mastodon/Scene/Thread/ThreadViewController.swift
index c1d580a71..a0de13477 100644
--- a/Mastodon/Scene/Thread/ThreadViewController.swift
+++ b/Mastodon/Scene/Thread/ThreadViewController.swift
@@ -97,7 +97,7 @@ extension ThreadViewController {
self.titleView.update(title: "", subtitle: nil)
return
}
- let mastodonContent = MastodonContent(content: title, emojis: emojiMeta ?? [:])
+ let mastodonContent = MastodonContent(content: title, emojis: emojiMeta)
do {
let metaContent = try MastodonMetaContent.convert(document: mastodonContent)
self.titleView.update(titleMetaContent: metaContent, subtitle: nil)
diff --git a/Mastodon/Scene/Thread/ThreadViewModel.swift b/Mastodon/Scene/Thread/ThreadViewModel.swift
index 1c4a7071e..7c2f07c31 100644
--- a/Mastodon/Scene/Thread/ThreadViewModel.swift
+++ b/Mastodon/Scene/Thread/ThreadViewModel.swift
@@ -88,7 +88,7 @@ class ThreadViewModel {
}
self.rootNode.value = RootNode(domain: status.domain, statusID: status.id, replyToID: status.inReplyToID)
self.navigationBarTitle.value = L10n.Scene.Thread.title(status.author.displayNameWithFallback)
- self.navigationBarTitleEmojiMeta.value = status.author.emojiMeta ?? [:]
+ self.navigationBarTitleEmojiMeta.value = status.author.emojiMeta
}
}
.store(in: &disposeBag)
diff --git a/Mastodon/Service/APIService/APIService+APIError.swift b/Mastodon/Service/APIService/APIService+APIError.swift
index 352be4ff4..181495cf4 100644
--- a/Mastodon/Service/APIService/APIService+APIError.swift
+++ b/Mastodon/Service/APIService/APIService+APIError.swift
@@ -65,7 +65,7 @@ extension APIService.APIError: LocalizedError {
case .badRequest: return "Request invalid."
case .badResponse: return "Response invalid."
case .requestThrottle: return "Request too frequency."
- case .voteExpiredPoll: return L10n.Common.Alerts.VoteFailure.pollExpired
+ case .voteExpiredPoll: return L10n.Common.Alerts.VoteFailure.pollEnded
case .mastodonAPIError(let error):
guard let responseError = error.mastodonError else {
return nil
diff --git a/Mastodon/Service/PlaybackState.swift b/Mastodon/Service/PlaybackState.swift
index 8e62fa145..3dfaa4d0d 100644
--- a/Mastodon/Service/PlaybackState.swift
+++ b/Mastodon/Service/PlaybackState.swift
@@ -35,9 +35,6 @@ extension PlaybackState: CustomStringConvertible {
case .paused: return "paused"
case .stopped: return "stopped"
case .failed: return "failed"
- default:
- assertionFailure()
- return ""
}
}
}
diff --git a/ShareActionExtension/Scene/ShareViewController.swift b/ShareActionExtension/Scene/ShareViewController.swift
index e72c46196..765c42d1e 100644
--- a/ShareActionExtension/Scene/ShareViewController.swift
+++ b/ShareActionExtension/Scene/ShareViewController.swift
@@ -169,11 +169,11 @@ extension ShareViewController {
case _ where count < 0:
self.composeToolbarView.characterCountLabel.font = .monospacedDigitSystemFont(ofSize: 24, weight: .bold)
self.composeToolbarView.characterCountLabel.textColor = Asset.Colors.danger.color
- self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitExceedsCount(abs(count))
+ self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitExceeds(abs(count))
default:
self.composeToolbarView.characterCountLabel.font = .monospacedDigitSystemFont(ofSize: 15, weight: .regular)
self.composeToolbarView.characterCountLabel.textColor = Asset.Colors.Label.secondary.color
- self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitRemainsCount(count)
+ self.composeToolbarView.characterCountLabel.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(count)
}
}
.store(in: &disposeBag)
diff --git a/ShareActionExtension/Scene/View/ComposeToolbarView.swift b/ShareActionExtension/Scene/View/ComposeToolbarView.swift
index d161e96fe..e6842c744 100644
--- a/ShareActionExtension/Scene/View/ComposeToolbarView.swift
+++ b/ShareActionExtension/Scene/View/ComposeToolbarView.swift
@@ -46,7 +46,7 @@ final class ComposeToolbarView: UIView {
label.font = .systemFont(ofSize: 15, weight: .regular)
label.text = "500"
label.textColor = Asset.Colors.Label.secondary.color
- label.accessibilityLabel = L10n.Scene.Compose.Accessibility.inputLimitRemainsCount(500)
+ label.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(500)
return label
}()