From a6d959a6b9ec4282a981ae3925a2fad7a4a71cfb Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Wed, 2 Dec 2020 17:41:22 -0800 Subject: [PATCH] Localized title --- Localizations/Localizable.strings | 2 ++ .../Services/AccountListService.swift | 15 ++++++++++++++- .../ServiceLayer/Services/AccountService.swift | 6 ++++-- .../ServiceLayer/Services/CollectionService.swift | 3 +++ View Controllers/TableViewController.swift | 9 +++++++++ .../ViewModels/CollectionItemsViewModel.swift | 4 ++++ .../Sources/ViewModels/CollectionViewModel.swift | 1 + .../Sources/ViewModels/ProfileViewModel.swift | 4 ++++ 8 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Localizations/Localizable.strings b/Localizations/Localizable.strings index 181a323..2a4d986 100644 --- a/Localizations/Localizable.strings +++ b/Localizations/Localizable.strings @@ -1,10 +1,12 @@ // Copyright © 2020 Metabolist. All rights reserved. +"account.%@-followers" = "%@'s Followers"; "account.block" = "Block"; "account.field.verified" = "Verified %@"; "account.follow" = "Follow"; "account.following" = "Following"; "account.following-count" = "%ld Following"; +"account.followed-by-%@" = "Followed by %@"; "account.hide-reblogs" = "Hide boosts"; "account.mute" = "Mute"; "account.request" = "Request"; diff --git a/ServiceLayer/Sources/ServiceLayer/Services/AccountListService.swift b/ServiceLayer/Sources/ServiceLayer/Services/AccountListService.swift index 56f6471..b595d25 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/AccountListService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/AccountListService.swift @@ -15,13 +15,18 @@ public struct AccountListService { private let endpoint: AccountsEndpoint private let mastodonAPIClient: MastodonAPIClient private let contentDatabase: ContentDatabase + private let titleComponents: [String]? private let nextPageMaxIdSubject = PassthroughSubject() - init(endpoint: AccountsEndpoint, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) { + init(endpoint: AccountsEndpoint, + mastodonAPIClient: MastodonAPIClient, + contentDatabase: ContentDatabase, + titleComponents: [String]? = nil) { list = AccountList() self.endpoint = endpoint self.mastodonAPIClient = mastodonAPIClient self.contentDatabase = contentDatabase + self.titleComponents = titleComponents sections = contentDatabase.accountListPublisher(list) .map { [$0.map(CollectionItem.account)] } .eraseToAnyPublisher() @@ -41,4 +46,12 @@ extension AccountListService: CollectionService { .flatMap { contentDatabase.append(accounts: $0.result, toList: list) } .eraseToAnyPublisher() } + + public var titleLocalizationComponents: AnyPublisher<[String], Never> { + if let titleComponents = titleComponents { + return Just(titleComponents).eraseToAnyPublisher() + } else { + return Empty().eraseToAnyPublisher() + } + } } diff --git a/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift b/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift index 13ad409..d86aec0 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift @@ -95,14 +95,16 @@ public extension AccountService { AccountListService( endpoint: .accountsFollowing(id: account.id), mastodonAPIClient: mastodonAPIClient, - contentDatabase: contentDatabase) + contentDatabase: contentDatabase, + titleComponents: ["account.followed-by-%@", "@".appending(account.acct)]) } func followersService() -> AccountListService { AccountListService( endpoint: .accountsFollowers(id: account.id), mastodonAPIClient: mastodonAPIClient, - contentDatabase: contentDatabase) + contentDatabase: contentDatabase, + titleComponents: ["account.%@-followers", "@".appending(account.acct)]) } } diff --git a/ServiceLayer/Sources/ServiceLayer/Services/CollectionService.swift b/ServiceLayer/Sources/ServiceLayer/Services/CollectionService.swift index 11053ec..2265fac 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/CollectionService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/CollectionService.swift @@ -7,6 +7,7 @@ public protocol CollectionService { var sections: AnyPublisher<[[CollectionItem]], Error> { get } var nextPageMaxId: AnyPublisher { get } var title: AnyPublisher { get } + var titleLocalizationComponents: AnyPublisher<[String], Never> { get } var navigationService: NavigationService { get } var markerTimeline: Marker.Timeline? { get } func request(maxId: String?, minId: String?) -> AnyPublisher @@ -17,5 +18,7 @@ extension CollectionService { public var title: AnyPublisher { Empty().eraseToAnyPublisher() } + public var titleLocalizationComponents: AnyPublisher<[String], Never> { Empty().eraseToAnyPublisher() } + public var markerTimeline: Marker.Timeline? { nil } } diff --git a/View Controllers/TableViewController.swift b/View Controllers/TableViewController.swift index 7d757e8..a57d635 100644 --- a/View Controllers/TableViewController.swift +++ b/View Controllers/TableViewController.swift @@ -228,6 +228,15 @@ private extension TableViewController { func setupViewModelBindings() { viewModel.title.sink { [weak self] in self?.navigationItem.title = $0 }.store(in: &cancellables) + viewModel.titleLocalizationComponents.sink { [weak self] in + guard let key = $0.first else { return } + + self?.navigationItem.title = String( + format: NSLocalizedString(key, comment: ""), + arguments: Array($0.suffix(from: 1))) + } + .store(in: &cancellables) + viewModel.updates.sink { [weak self] in self?.update($0) }.store(in: &cancellables) viewModel.events.receive(on: DispatchQueue.main) diff --git a/ViewModels/Sources/ViewModels/CollectionItemsViewModel.swift b/ViewModels/Sources/ViewModels/CollectionItemsViewModel.swift index 840af2c..6de8db9 100644 --- a/ViewModels/Sources/ViewModels/CollectionItemsViewModel.swift +++ b/ViewModels/Sources/ViewModels/CollectionItemsViewModel.swift @@ -66,6 +66,10 @@ extension CollectionItemsViewModel: CollectionViewModel { public var title: AnyPublisher { collectionService.title } + public var titleLocalizationComponents: AnyPublisher<[String], Never> { + collectionService.titleLocalizationComponents + } + public var expandAll: AnyPublisher { expandAllSubject.eraseToAnyPublisher() } diff --git a/ViewModels/Sources/ViewModels/CollectionViewModel.swift b/ViewModels/Sources/ViewModels/CollectionViewModel.swift index f47adbc..ad40407 100644 --- a/ViewModels/Sources/ViewModels/CollectionViewModel.swift +++ b/ViewModels/Sources/ViewModels/CollectionViewModel.swift @@ -6,6 +6,7 @@ import Foundation public protocol CollectionViewModel { var updates: AnyPublisher { get } var title: AnyPublisher { get } + var titleLocalizationComponents: AnyPublisher<[String], Never> { get } var expandAll: AnyPublisher { get } var alertItems: AnyPublisher { get } var loading: AnyPublisher { get } diff --git a/ViewModels/Sources/ViewModels/ProfileViewModel.swift b/ViewModels/Sources/ViewModels/ProfileViewModel.swift index 9f32bb9..de5dc72 100644 --- a/ViewModels/Sources/ViewModels/ProfileViewModel.swift +++ b/ViewModels/Sources/ViewModels/ProfileViewModel.swift @@ -70,6 +70,10 @@ extension ProfileViewModel: CollectionViewModel { $accountViewModel.compactMap { $0?.accountName }.eraseToAnyPublisher() } + public var titleLocalizationComponents: AnyPublisher<[String], Never> { + collectionViewModel.flatMap(\.titleLocalizationComponents).eraseToAnyPublisher() + } + public var expandAll: AnyPublisher { Empty().eraseToAnyPublisher() }