mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-21 15:50:59 +00:00
Status word preference
This commit is contained in:
parent
f5aacf7624
commit
5f03ce7d8b
15 changed files with 163 additions and 71 deletions
|
@ -573,9 +573,9 @@ public extension ContentDatabase {
|
|||
|
||||
return accountsPublisher.combineLatest(statusesPublisher)
|
||||
.map { accounts, statuses in
|
||||
[.init(items: accounts, titleLocalizedStringKey: "search.scope.accounts"),
|
||||
.init(items: statuses, titleLocalizedStringKey: "search.scope.statuses"),
|
||||
.init(items: hashtags, titleLocalizedStringKey: "search.scope.tags")]
|
||||
[.init(items: accounts, searchScope: .accounts),
|
||||
.init(items: statuses, searchScope: .statuses),
|
||||
.init(items: hashtags, searchScope: .tags)]
|
||||
.filter { !$0.items.isEmpty }
|
||||
}
|
||||
.removeDuplicates()
|
||||
|
|
|
@ -4,10 +4,10 @@ import Foundation
|
|||
|
||||
public struct CollectionSection: Hashable {
|
||||
public let items: [CollectionItem]
|
||||
public let titleLocalizedStringKey: String?
|
||||
public let searchScope: SearchScope?
|
||||
|
||||
public init(items: [CollectionItem], titleLocalizedStringKey: String? = nil) {
|
||||
public init(items: [CollectionItem], searchScope: SearchScope? = nil) {
|
||||
self.items = items
|
||||
self.titleLocalizedStringKey = titleLocalizedStringKey
|
||||
self.searchScope = searchScope
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@ import ViewModels
|
|||
final class TableViewDataSource: UITableViewDiffableDataSource<CollectionSection.Identifier, CollectionItem> {
|
||||
private let updateQueue =
|
||||
DispatchQueue(label: "com.metabolist.metatext.collection-data-source.update-queue")
|
||||
private let viewModel: CollectionViewModel
|
||||
|
||||
init(tableView: UITableView, viewModel: CollectionViewModel) {
|
||||
self.viewModel = viewModel
|
||||
|
||||
init(tableView: UITableView, viewModelProvider: @escaping (IndexPath) -> CollectionItemViewModel) {
|
||||
for cellClass in CollectionItem.cellClasses {
|
||||
tableView.register(cellClass, forCellReuseIdentifier: String(describing: cellClass))
|
||||
}
|
||||
|
@ -17,7 +20,7 @@ final class TableViewDataSource: UITableViewDiffableDataSource<CollectionSection
|
|||
withIdentifier: String(describing: item.cellClass),
|
||||
for: indexPath)
|
||||
|
||||
switch (cell, viewModelProvider(indexPath)) {
|
||||
switch (cell, viewModel.viewModel(indexPath: indexPath)) {
|
||||
case let (statusCell as StatusTableViewCell, statusViewModel as StatusViewModel):
|
||||
statusCell.viewModel = statusViewModel
|
||||
case let (accountCell as AccountTableViewCell, accountViewModel as AccountViewModel):
|
||||
|
@ -32,8 +35,9 @@ final class TableViewDataSource: UITableViewDiffableDataSource<CollectionSection
|
|||
tagCell.viewModel = tagViewModel
|
||||
case let (_, moreResultsViewModel as MoreResultsViewModel):
|
||||
var configuration = cell.defaultContentConfiguration()
|
||||
let statusWord = viewModel.identityContext.appPreferences.statusWord
|
||||
|
||||
configuration.text = moreResultsViewModel.scope.moreDescription
|
||||
configuration.text = moreResultsViewModel.scope.moreDescription(statusWord: statusWord)
|
||||
|
||||
cell.contentConfiguration = configuration
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
|
@ -58,8 +62,8 @@ final class TableViewDataSource: UITableViewDiffableDataSource<CollectionSection
|
|||
let section = currentSnapshot.sectionIdentifiers[section]
|
||||
|
||||
if currentSnapshot.numberOfItems(inSection: section) > 0,
|
||||
let localizedStringKey = section.titleLocalizedStringKey {
|
||||
return NSLocalizedString(localizedStringKey, comment: "")
|
||||
let searchScope = section.searchScope {
|
||||
return searchScope.title(statusWord: viewModel.identityContext.appPreferences.statusWord)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -6,7 +6,7 @@ import ViewModels
|
|||
extension CollectionSection {
|
||||
struct Identifier: Hashable {
|
||||
let index: Int
|
||||
let titleLocalizedStringKey: String?
|
||||
let searchScope: SearchScope?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ extension Array where Element == CollectionSection {
|
|||
for (index, section) in enumerated() {
|
||||
let identifier = CollectionSection.Identifier(
|
||||
index: index,
|
||||
titleLocalizedStringKey: section.titleLocalizedStringKey)
|
||||
searchScope: section.searchScope)
|
||||
snapshot.appendSections([identifier])
|
||||
snapshot.appendItems(section.items, toSection: identifier)
|
||||
}
|
||||
|
|
|
@ -4,12 +4,22 @@ import Foundation
|
|||
import ViewModels
|
||||
|
||||
extension ProfileCollection {
|
||||
var title: String {
|
||||
func title(statusWord: AppPreferences.StatusWord) -> String {
|
||||
switch self {
|
||||
case .statuses:
|
||||
return NSLocalizedString("account.statuses", comment: "")
|
||||
switch statusWord {
|
||||
case .toot:
|
||||
return NSLocalizedString("account.statuses.toot", comment: "")
|
||||
case .post:
|
||||
return NSLocalizedString("account.statuses.post", comment: "")
|
||||
}
|
||||
case .statusesAndReplies:
|
||||
return NSLocalizedString("account.statuses-and-replies", comment: "")
|
||||
switch statusWord {
|
||||
case .toot:
|
||||
return NSLocalizedString("account.statuses-and-replies.toot", comment: "")
|
||||
default:
|
||||
return NSLocalizedString("account.statuses-and-replies.post", comment: "")
|
||||
}
|
||||
case .media:
|
||||
return NSLocalizedString("account.media", comment: "")
|
||||
}
|
||||
|
|
|
@ -4,27 +4,38 @@ import Foundation
|
|||
import ViewModels
|
||||
|
||||
extension SearchScope {
|
||||
var title: String {
|
||||
func title(statusWord: AppPreferences.StatusWord) -> String {
|
||||
switch self {
|
||||
case .all:
|
||||
return NSLocalizedString("search.scope.all", comment: "")
|
||||
case .accounts:
|
||||
return NSLocalizedString("search.scope.accounts", comment: "")
|
||||
case .statuses:
|
||||
return NSLocalizedString("search.scope.statuses", comment: "")
|
||||
switch statusWord {
|
||||
case .toot:
|
||||
return NSLocalizedString("search.scope.statuses.toot", comment: "")
|
||||
case .post:
|
||||
return NSLocalizedString("search.scope.statuses.post", comment: "")
|
||||
}
|
||||
case .tags:
|
||||
return NSLocalizedString("search.scope.tags", comment: "")
|
||||
}
|
||||
}
|
||||
|
||||
var moreDescription: String? {
|
||||
func moreDescription(statusWord: AppPreferences.StatusWord) -> String? {
|
||||
switch self {
|
||||
case .all:
|
||||
return nil
|
||||
case .accounts:
|
||||
return NSLocalizedString("more-results.accounts", comment: "")
|
||||
case .statuses:
|
||||
return NSLocalizedString("more-results.statuses", comment: "")
|
||||
switch statusWord {
|
||||
case .toot:
|
||||
return NSLocalizedString("more-results.statuses.toot", comment: "")
|
||||
case .post:
|
||||
return NSLocalizedString("more-results.statuses.post", comment: "")
|
||||
}
|
||||
|
||||
case .tags:
|
||||
return NSLocalizedString("more-results.tags", comment: "")
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
"account.hide-reblogs" = "Hide boosts";
|
||||
"account.mute" = "Mute";
|
||||
"account.request" = "Request";
|
||||
"account.statuses" = "Posts";
|
||||
"account.statuses-and-replies" = "Posts & Replies";
|
||||
"account.statuses.post" = "Posts";
|
||||
"account.statuses.toot" = "Toots";
|
||||
"account.statuses-and-replies.post" = "Posts & Replies";
|
||||
"account.statuses-and-replies.toot" = "Toots & Replies";
|
||||
"account.media" = "Media";
|
||||
"account.show-reblogs" = "Show boosts";
|
||||
"account.unavailable" = "Profile unavailable";
|
||||
|
@ -129,12 +131,9 @@
|
|||
"preferences.media.autoplay.always" = "Always";
|
||||
"preferences.media.autoplay.wifi" = "On Wi-Fi";
|
||||
"preferences.media.autoplay.never" = "Never";
|
||||
"preferences.posting-reading" = "Posting and Reading";
|
||||
"preferences.posting" = "Posting";
|
||||
"preferences.use-preferences-from-server" = "Use preferences from server";
|
||||
"preferences.posting-default-visiblility" = "Default visibility";
|
||||
"preferences.posting-default-sensitive" = "Mark content sensitive by default";
|
||||
"preferences.reading" = "Reading";
|
||||
"preferences.reading-expand-media" = "Expand media";
|
||||
"preferences.expand-media.default" = "Hide sensitive";
|
||||
"preferences.expand-media.show-all" = "Show all";
|
||||
|
@ -156,6 +155,7 @@
|
|||
"preferences.position.sync-position" = "Sync position with web and other devices";
|
||||
"preferences.position.newest" = "Load newest";
|
||||
"preferences.show-reblog-and-favorite-counts" = "Show reblog and favorite counts";
|
||||
"preferences.status-word" = "Status word";
|
||||
"filters.active" = "Active";
|
||||
"filters.expired" = "Expired";
|
||||
"filter.add-new" = "Add New Filter";
|
||||
|
@ -165,7 +165,7 @@
|
|||
"filter.expire-after" = "Expire after";
|
||||
"filter.contexts" = "Filter contexts";
|
||||
"filter.irreversible" = "Drop instead of hide";
|
||||
"filter.irreversible-explanation" = "Filtered posts will disappear irreversibly, even if filter is later removed";
|
||||
"filter.irreversible-explanation" = "Filtered statuses will disappear irreversibly, even if filter is later removed";
|
||||
"filter.whole-word" = "Whole word";
|
||||
"filter.whole-word-explanation" = "When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word";
|
||||
"filter.save-changes" = "Save Changes";
|
||||
|
@ -176,7 +176,8 @@
|
|||
"filter.context.account" = "Profiles";
|
||||
"filter.context.unknown" = "Unknown context";
|
||||
"more-results.accounts" = "More people";
|
||||
"more-results.statuses" = "More posts";
|
||||
"more-results.statuses.post" = "More posts";
|
||||
"more-results.statuses.toot" = "More toots";
|
||||
"more-results.tags" = "More hashtags";
|
||||
"notifications" = "Notifications";
|
||||
"notifications.reblogged-your-status" = "%@ boosted your status";
|
||||
|
@ -194,18 +195,22 @@
|
|||
"report.forward-%@" = "Forward report to %@";
|
||||
"search.scope.all" = "All";
|
||||
"search.scope.accounts" = "People";
|
||||
"search.scope.statuses" = "Posts";
|
||||
"search.scope.statuses.post" = "Posts";
|
||||
"search.scope.statuses.toot" = "Toots";
|
||||
"search.scope.tags" = "Hashtags";
|
||||
"share-extension-error.no-account-found" = "No account found";
|
||||
"status.bookmark" = "Bookmark";
|
||||
"status.content-warning-abbreviation" = "CW";
|
||||
"status.delete" = "Delete";
|
||||
"status.delete.confirm" = "Are you sure you want to delete this post?";
|
||||
"status.delete.confirm.post" = "Are you sure you want to delete this post?";
|
||||
"status.delete.confirm.toot" = "Are you sure you want to delete this toot?";
|
||||
"status.delete-and-redraft" = "Delete & re-draft";
|
||||
"status.delete-and-redraft.confirm" = "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.";
|
||||
"status.delete-and-redraft.confirm.post" = "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.";
|
||||
"status.delete-and-redraft.confirm.toot" = "Are you sure you want to delete this toot and re-draft it? Favorites and boosts will be lost, and replies to the original toot will be orphaned.";
|
||||
"status.mute" = "Mute conversation";
|
||||
"status.pin" = "Pin on profile";
|
||||
"status.pinned-post" = "Pinned post";
|
||||
"status.pinned.post" = "Pinned post";
|
||||
"status.pinned.toot" = "Pinned toot";
|
||||
"status.poll.vote" = "Vote";
|
||||
"status.poll.time-left" = "%@ left";
|
||||
"status.poll.refresh" = "Refresh";
|
||||
|
@ -229,3 +234,4 @@
|
|||
"timelines.home" = "Home";
|
||||
"timelines.local" = "Local";
|
||||
"timelines.federated" = "Federated";
|
||||
"toot" = "Toot";
|
||||
|
|
|
@ -15,6 +15,13 @@ public struct AppPreferences {
|
|||
}
|
||||
|
||||
public extension AppPreferences {
|
||||
enum StatusWord: String, CaseIterable, Identifiable {
|
||||
case toot
|
||||
case post
|
||||
|
||||
public var id: String { rawValue }
|
||||
}
|
||||
|
||||
enum AnimateAvatars: String, CaseIterable, Identifiable {
|
||||
case everywhere
|
||||
case profiles
|
||||
|
@ -44,6 +51,18 @@ public extension AppPreferences {
|
|||
set { self[.useSystemReduceMotionForMedia] = newValue }
|
||||
}
|
||||
|
||||
var statusWord: StatusWord {
|
||||
get {
|
||||
if let rawValue = self[.statusWord] as String?,
|
||||
let value = StatusWord(rawValue: rawValue) {
|
||||
return value
|
||||
}
|
||||
|
||||
return .toot
|
||||
}
|
||||
set { self[.statusWord] = newValue.rawValue }
|
||||
}
|
||||
|
||||
var animateAvatars: AnimateAvatars {
|
||||
get {
|
||||
if let rawValue = self[.animateAvatars] as String?,
|
||||
|
@ -140,23 +159,9 @@ public extension AppPreferences {
|
|||
}
|
||||
}
|
||||
|
||||
extension AppPreferences {
|
||||
var updatedInstanceFilter: BloomFilter<String>? {
|
||||
guard let data = self[.updatedFilter] as Data? else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return try? JSONDecoder().decode(BloomFilter<String>.self, from: data)
|
||||
}
|
||||
|
||||
func updateInstanceFilter( _ filter: BloomFilter<String>) {
|
||||
userDefaults.set(try? JSONEncoder().encode(filter), forKey: Item.updatedFilter.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
private extension AppPreferences {
|
||||
enum Item: String {
|
||||
case updatedFilter
|
||||
case statusWord
|
||||
case useSystemReduceMotionForMedia
|
||||
case animateAvatars
|
||||
case animateHeaders
|
||||
|
|
|
@ -53,10 +53,16 @@ final class ExploreViewController: UICollectionViewController {
|
|||
|
||||
let searchController = UISearchController(searchResultsController: searchResultsController)
|
||||
|
||||
searchController.searchBar.scopeButtonTitles = SearchScope.allCases.map(\.title)
|
||||
searchController.searchResultsUpdater = self
|
||||
navigationItem.searchController = searchController
|
||||
|
||||
viewModel.identityContext.$appPreferences.sink { appPreferences in
|
||||
searchController.searchBar.scopeButtonTitles = SearchScope.allCases.map {
|
||||
$0.title(statusWord: appPreferences.statusWord)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
viewModel.events.sink { [weak self] in self?.handle(event: $0) }.store(in: &cancellables)
|
||||
|
||||
viewModel.$loading.sink { [weak self] in
|
||||
|
|
|
@ -15,7 +15,7 @@ final class NewStatusViewController: UIViewController {
|
|||
private let stackView = UIStackView()
|
||||
private let activityIndicatorView = UIActivityIndicatorView(style: .large)
|
||||
private let postButton = UIBarButtonItem(
|
||||
title: NSLocalizedString("post", comment: ""),
|
||||
title: nil,
|
||||
style: .done,
|
||||
target: nil,
|
||||
action: nil)
|
||||
|
@ -40,6 +40,7 @@ final class NewStatusViewController: UIViewController {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
|
@ -76,7 +77,16 @@ final class NewStatusViewController: UIViewController {
|
|||
primaryAction: UIAction { [weak self] _ in self?.dismiss() })
|
||||
navigationItem.rightBarButtonItem = postButton
|
||||
|
||||
postButton.primaryAction = UIAction(title: NSLocalizedString("post", comment: "")) { [weak self] _ in
|
||||
let postActionTitle: String
|
||||
|
||||
switch viewModel.identityContext.appPreferences.statusWord {
|
||||
case .toot:
|
||||
postActionTitle = NSLocalizedString("toot", comment: "")
|
||||
case .post:
|
||||
postActionTitle = NSLocalizedString("post", comment: "")
|
||||
}
|
||||
|
||||
postButton.primaryAction = UIAction(title: postActionTitle) { [weak self] _ in
|
||||
self?.viewModel.post()
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,7 @@ final class ProfileViewController: TableViewController {
|
|||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Initial size is to avoid unsatisfiable constraint warning
|
||||
let accountHeaderView = AccountHeaderView(frame: .init(origin: .zero, size: .init(width: 300, height: 300)))
|
||||
|
||||
accountHeaderView.viewModel = viewModel
|
||||
let accountHeaderView = AccountHeaderView(viewModel: viewModel)
|
||||
|
||||
viewModel.$accountViewModel
|
||||
.receive(on: DispatchQueue.main)
|
||||
|
|
|
@ -24,7 +24,7 @@ class TableViewController: UITableViewController {
|
|||
private weak var parentNavigationController: UINavigationController?
|
||||
|
||||
private lazy var dataSource: TableViewDataSource = {
|
||||
.init(tableView: tableView, viewModelProvider: viewModel.viewModel(indexPath:))
|
||||
.init(tableView: tableView, viewModel: viewModel)
|
||||
}()
|
||||
|
||||
init(viewModel: CollectionViewModel,
|
||||
|
@ -441,11 +441,23 @@ private extension TableViewController {
|
|||
}
|
||||
|
||||
func confirmDelete(statusViewModel: StatusViewModel, redraft: Bool) {
|
||||
let deleteAndRedraftConfirmMessage: String
|
||||
let deleteConfirmMessage: String
|
||||
|
||||
switch viewModel.identityContext.appPreferences.statusWord {
|
||||
case .toot:
|
||||
deleteAndRedraftConfirmMessage = NSLocalizedString("status.delete-and-redraft.confirm.toot", comment: "")
|
||||
deleteConfirmMessage = NSLocalizedString("status.delete.confirm.toot", comment: "")
|
||||
case .post:
|
||||
deleteAndRedraftConfirmMessage = NSLocalizedString("status.delete-and-redraft.confirm.post", comment: "")
|
||||
deleteConfirmMessage = NSLocalizedString("status.delete.confirm.post", comment: "")
|
||||
}
|
||||
|
||||
let alertController = UIAlertController(
|
||||
title: nil,
|
||||
message: redraft
|
||||
? NSLocalizedString("status.delete-and-redraft.confirm", comment: "")
|
||||
: NSLocalizedString("status.delete.confirm", comment: ""),
|
||||
? deleteAndRedraftConfirmMessage
|
||||
: deleteConfirmMessage,
|
||||
preferredStyle: .alert)
|
||||
|
||||
let deleteAction = UIAlertAction(
|
||||
|
|
|
@ -62,6 +62,12 @@ struct PreferencesView: View {
|
|||
.disabled(viewModel.preferences.useServerPostingReadingPreferences)
|
||||
}
|
||||
Section(header: Text("preferences.app")) {
|
||||
Picker("preferences.status-word",
|
||||
selection: $identityContext.appPreferences.statusWord) {
|
||||
ForEach(AppPreferences.StatusWord.allCases) { option in
|
||||
Text(option.localizedStringKey).tag(option)
|
||||
}
|
||||
}
|
||||
if accessibilityReduceMotion {
|
||||
Toggle("preferences.media.use-system-reduce-motion",
|
||||
isOn: $identityContext.appPreferences.useSystemReduceMotionForMedia)
|
||||
|
@ -119,6 +125,17 @@ private extension PreferencesView {
|
|||
}
|
||||
}
|
||||
|
||||
extension AppPreferences.StatusWord {
|
||||
var localizedStringKey: LocalizedStringKey {
|
||||
switch self {
|
||||
case .toot:
|
||||
return "toot"
|
||||
case .post:
|
||||
return "post"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AppPreferences.AnimateAvatars {
|
||||
var localizedStringKey: LocalizedStringKey {
|
||||
switch self {
|
||||
|
|
|
@ -26,9 +26,9 @@ final class AccountHeaderView: UIView {
|
|||
let segmentedControl = UISegmentedControl()
|
||||
let unavailableLabel = UILabel()
|
||||
|
||||
var viewModel: ProfileViewModel? {
|
||||
var viewModel: ProfileViewModel {
|
||||
didSet {
|
||||
if let accountViewModel = viewModel?.accountViewModel {
|
||||
if let accountViewModel = viewModel.accountViewModel {
|
||||
headerImageView.kf.setImage(with: accountViewModel.headerURL) { [weak self] in
|
||||
if case let .success(result) = $0, result.image.size != Self.missingHeaderImageSize {
|
||||
self?.headerButton.isEnabled = true
|
||||
|
@ -127,8 +127,11 @@ final class AccountHeaderView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
init(viewModel: ProfileViewModel) {
|
||||
self.viewModel = viewModel
|
||||
|
||||
// Initial size is to avoid unsatisfiable constraint warning
|
||||
super.init(frame: .init(origin: .zero, size: .init(width: 300, height: 300)))
|
||||
|
||||
initialSetup()
|
||||
}
|
||||
|
@ -158,7 +161,7 @@ extension AccountHeaderView: UITextViewDelegate {
|
|||
interaction: UITextItemInteraction) -> Bool {
|
||||
switch interaction {
|
||||
case .invokeDefaultAction:
|
||||
viewModel?.accountViewModel?.urlSelected(URL)
|
||||
viewModel.accountViewModel?.urlSelected(URL)
|
||||
return false
|
||||
case .preview: return false
|
||||
case .presentActions: return false
|
||||
|
@ -189,7 +192,7 @@ private extension AccountHeaderView {
|
|||
headerButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
headerButton.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)
|
||||
|
||||
headerButton.addAction(UIAction { [weak self] _ in self?.viewModel?.presentHeader() }, for: .touchUpInside)
|
||||
headerButton.addAction(UIAction { [weak self] _ in self?.viewModel.presentHeader() }, for: .touchUpInside)
|
||||
headerButton.isEnabled = false
|
||||
|
||||
let avatarBackgroundViewDimension = Self.avatarDimension + .compactSpacing * 2
|
||||
|
@ -210,7 +213,7 @@ private extension AccountHeaderView {
|
|||
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
avatarButton.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)
|
||||
|
||||
avatarButton.addAction(UIAction { [weak self] _ in self?.viewModel?.presentAvatar() }, for: .touchUpInside)
|
||||
avatarButton.addAction(UIAction { [weak self] _ in self?.viewModel.presentAvatar() }, for: .touchUpInside)
|
||||
|
||||
addSubview(relationshipButtonsStackView)
|
||||
relationshipButtonsStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
@ -230,7 +233,7 @@ private extension AccountHeaderView {
|
|||
withConfiguration: UIImage.SymbolConfiguration(scale: .small)),
|
||||
for: .normal)
|
||||
followButton.addAction(
|
||||
UIAction { [weak self] _ in self?.viewModel?.accountViewModel?.follow() },
|
||||
UIAction { [weak self] _ in self?.viewModel.accountViewModel?.follow() },
|
||||
for: .touchUpInside)
|
||||
|
||||
unfollowButton.setImage(
|
||||
|
@ -241,7 +244,7 @@ private extension AccountHeaderView {
|
|||
unfollowButton.setTitle(NSLocalizedString("account.following", comment: ""), for: .normal)
|
||||
unfollowButton.showsMenuAsPrimaryAction = true
|
||||
unfollowButton.menu = UIMenu(children: [UIDeferredMenuElement { [weak self] completion in
|
||||
guard let accountViewModel = self?.viewModel?.accountViewModel else { return }
|
||||
guard let accountViewModel = self?.viewModel.accountViewModel else { return }
|
||||
|
||||
let unfollowAction = UIAction(
|
||||
title: NSLocalizedString("account.unfollow", comment: ""),
|
||||
|
@ -299,20 +302,22 @@ private extension AccountHeaderView {
|
|||
followStackView.distribution = .fillEqually
|
||||
|
||||
followingButton.addAction(
|
||||
UIAction { [weak self] _ in self?.viewModel?.accountViewModel?.followingSelected() },
|
||||
UIAction { [weak self] _ in self?.viewModel.accountViewModel?.followingSelected() },
|
||||
for: .touchUpInside)
|
||||
followStackView.addArrangedSubview(followingButton)
|
||||
|
||||
followersButton.addAction(
|
||||
UIAction { [weak self] _ in self?.viewModel?.accountViewModel?.followersSelected() },
|
||||
UIAction { [weak self] _ in self?.viewModel.accountViewModel?.followersSelected() },
|
||||
for: .touchUpInside)
|
||||
followStackView.addArrangedSubview(followersButton)
|
||||
|
||||
let statusWord = viewModel.identityContext.appPreferences.statusWord
|
||||
|
||||
for (index, collection) in ProfileCollection.allCases.enumerated() {
|
||||
segmentedControl.insertSegment(
|
||||
action: UIAction(title: collection.title) { [weak self] _ in
|
||||
self?.viewModel?.collection = collection
|
||||
self?.viewModel?.request(maxId: nil, minId: nil, search: nil)
|
||||
action: UIAction(title: collection.title(statusWord: statusWord)) { [weak self] _ in
|
||||
self?.viewModel.collection = collection
|
||||
self?.viewModel.request(maxId: nil, minId: nil, search: nil)
|
||||
},
|
||||
at: index,
|
||||
animated: false)
|
||||
|
|
|
@ -354,7 +354,16 @@ private extension StatusView {
|
|||
infoLabel.isHidden = false
|
||||
infoIcon.isHidden = false
|
||||
} else if viewModel.configuration.isPinned {
|
||||
infoLabel.text = NSLocalizedString("status.pinned-post", comment: "")
|
||||
let pinnedText: String
|
||||
|
||||
switch viewModel.identityContext.appPreferences.statusWord {
|
||||
case .toot:
|
||||
pinnedText = NSLocalizedString("status.pinned.toot", comment: "")
|
||||
case .post:
|
||||
pinnedText = NSLocalizedString("status.pinned.post", comment: "")
|
||||
}
|
||||
|
||||
infoLabel.text = pinnedText
|
||||
infoIcon.image = UIImage(
|
||||
systemName: "pin",
|
||||
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
|
||||
|
|
Loading…
Reference in a new issue