DM button

This commit is contained in:
Justin Mazzocchi 2021-03-01 16:53:36 -08:00
parent b235344268
commit a0141f7750
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
10 changed files with 61 additions and 13 deletions

View file

@ -11,6 +11,7 @@
"account.block-and-report" = "Block & report";
"account.block.confirm-%@" = "Block %@?";
"account.blocked" = "Blocked";
"account.direct-message" = "Direct message";
"account.domain-block-%@" = "Block domain %@";
"account.domain-block.confirm-%@" = "Block domain %@?";
"account.domain-unblock-%@" = "Unblock domain %@";

View file

@ -495,8 +495,8 @@ private extension TableViewController {
handle(navigation: navigation)
case let .attachment(attachmentViewModel, statusViewModel):
present(attachmentViewModel: attachmentViewModel, statusViewModel: statusViewModel)
case let .compose(inReplyToViewModel, redraft):
compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft)
case let .compose(inReplyToViewModel, redraft, directMessageTo):
compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft, directMessageTo: directMessageTo)
case let .confirmDelete(statusViewModel, redraft):
confirmDelete(statusViewModel: statusViewModel, redraft: redraft)
case let .confirmUnfollow(accountViewModel):
@ -595,11 +595,12 @@ private extension TableViewController {
}
}
func compose(inReplyToViewModel: StatusViewModel?, redraft: Status?) {
func compose(inReplyToViewModel: StatusViewModel?, redraft: Status?, directMessageTo: AccountViewModel?) {
rootViewModel?.navigationViewModel?.presentedNewStatusViewModel = rootViewModel?.newStatusViewModel(
identityContext: viewModel.identityContext,
inReplyTo: inReplyToViewModel,
redraft: redraft)
redraft: redraft,
directMessageTo: directMessageTo)
}
func confirmDelete(statusViewModel: StatusViewModel, redraft: Bool) {

View file

@ -9,7 +9,7 @@ public enum CollectionItemEvent {
case refresh
case navigation(Navigation)
case attachment(AttachmentViewModel, StatusViewModel)
case compose(inReplyTo: StatusViewModel?, redraft: Status?)
case compose(inReplyTo: StatusViewModel? = nil, redraft: Status? = nil, directMessageTo: AccountViewModel? = nil)
case confirmDelete(StatusViewModel, redraft: Bool)
case confirmUnfollow(AccountViewModel)
case confirmHideReblogs(AccountViewModel)

View file

@ -358,6 +358,15 @@ extension CollectionItemsViewModel: CollectionViewModel {
}
}
extension CollectionItemsViewModel {
func sendDirectMessage(accountViewModel: AccountViewModel) {
eventsSubject.send(
Just(.compose(directMessageTo: accountViewModel))
.setFailureType(to: Error.self)
.eraseToAnyPublisher())
}
}
private extension CollectionItemsViewModel {
private static let lastReadIdDebounceInterval: TimeInterval = 0.5

View file

@ -29,6 +29,7 @@ public final class NewStatusViewModel: ObservableObject {
environment: AppEnvironment,
inReplyTo: StatusViewModel?,
redraft: Status?,
directMessageTo: AccountViewModel?,
extensionContext: NSExtensionContext?) {
self.allIdentitiesService = allIdentitiesService
self.identityContext = identityContext
@ -78,6 +79,9 @@ public final class NewStatusViewModel: ObservableObject {
.map("@".appending))
compositionViewModel.text = mentions.joined(separator: " ").appending(" ")
} else if let directMessageTo = directMessageTo {
compositionViewModel.text = directMessageTo.accountName.appending(" ")
visibility = .direct
}
compositionViewModels = [compositionViewModel]

View file

@ -76,6 +76,12 @@ public extension ProfileViewModel {
func fetchProfile() -> AnyPublisher<Never, Never> {
profileService.fetchProfile().assignErrorsToAlertItem(to: \.alertItem, on: self)
}
func sendDirectMessage() {
guard let accountViewModel = accountViewModel else { return }
collectionViewModel.value.sendDirectMessage(accountViewModel: accountViewModel)
}
}
extension ProfileViewModel: CollectionViewModel {

View file

@ -68,13 +68,15 @@ public extension RootViewModel {
func newStatusViewModel(
identityContext: IdentityContext,
inReplyTo: StatusViewModel? = nil,
redraft: Status? = nil) -> NewStatusViewModel {
redraft: Status? = nil,
directMessageTo: AccountViewModel? = nil) -> NewStatusViewModel {
NewStatusViewModel(
allIdentitiesService: allIdentitiesService,
identityContext: identityContext,
environment: environment,
inReplyTo: inReplyTo,
redraft: redraft,
directMessageTo: directMessageTo,
extensionContext: nil)
}
}

View file

@ -39,6 +39,7 @@ public extension ShareExtensionNavigationViewModel {
environment: environment,
inReplyTo: nil,
redraft: nil,
directMessageTo: nil,
extensionContext: extensionContext)
}
}

View file

@ -250,7 +250,7 @@ public extension StatusViewModel {
replyViewModel.configuration = configuration.reply()
eventsSubject.send(
Just(.compose(inReplyTo: replyViewModel, redraft: nil))
Just(.compose(inReplyTo: replyViewModel))
.setFailureType(to: Error.self)
.eraseToAnyPublisher())
}

View file

@ -13,6 +13,7 @@ final class AccountHeaderView: UIView {
let avatarImageView = SDAnimatedImageView()
let avatarButton = UIButton()
let relationshipButtonsStackView = UIStackView()
let directMessageButton = UIButton()
let followButton = UIButton(type: .system)
let unfollowButton = UIButton(type: .system)
let notifyButton = UIButton()
@ -216,10 +217,18 @@ final class AccountHeaderView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
for button in [followButton, unfollowButton, notifyButton, unnotifyButton] {
let inset = (followButton.bounds.height - (button.titleLabel?.bounds.height ?? 0)) / 2
if let pointSize = followingButton.titleLabel?.font.pointSize {
relationshipButtonsStackView.heightAnchor
.constraint(equalToConstant: pointSize + .defaultSpacing * 2).isActive = true
}
for button in [followButton, unfollowButton] {
let inset = (button.bounds.height - (button.titleLabel?.bounds.height ?? 0))
button.contentEdgeInsets = .init(top: 0, left: inset, bottom: 0, right: inset)
}
for button in [directMessageButton, followButton, unfollowButton, notifyButton, unnotifyButton] {
button.layer.cornerRadius = button.bounds.height / 2
}
}
@ -299,19 +308,30 @@ private extension AccountHeaderView {
relationshipButtonsStackView.spacing = .defaultSpacing
relationshipButtonsStackView.addArrangedSubview(UIView())
for button in [followButton, unfollowButton, notifyButton, unnotifyButton] {
for button in [directMessageButton, notifyButton, unnotifyButton, followButton, unfollowButton] {
relationshipButtonsStackView.addArrangedSubview(button)
button.titleLabel?.font = .preferredFont(forTextStyle: .headline)
button.titleLabel?.adjustsFontForContentSizeCategory = true
button.backgroundColor = .secondarySystemBackground
}
directMessageButton.setImage(
UIImage(
systemName: "envelope",
withConfiguration: UIImage.SymbolConfiguration(scale: .small)),
for: .normal)
directMessageButton.accessibilityLabel = NSLocalizedString("account.direct-message", comment: "")
directMessageButton.addAction(
UIAction { [weak self] _ in self?.viewModel.sendDirectMessage() },
for: .touchUpInside)
followButton.setImage(
UIImage(
systemName: "person.badge.plus",
withConfiguration: UIImage.SymbolConfiguration(scale: .small)),
for: .normal)
followButton.isHidden = true
followButton.titleLabel?.adjustsFontSizeToFitWidth = true
followButton.addAction(
UIAction { [weak self] _ in self?.viewModel.accountViewModel?.follow() },
for: .touchUpInside)
@ -323,14 +343,16 @@ private extension AccountHeaderView {
for: .normal)
unfollowButton.setTitle(NSLocalizedString("account.following", comment: ""), for: .normal)
unfollowButton.isHidden = true
unfollowButton.titleLabel?.adjustsFontSizeToFitWidth = true
unfollowButton.addAction(
UIAction { [weak self] _ in self?.viewModel.accountViewModel?.confirmUnfollow() },
for: .touchUpInside)
notifyButton.setImage(
UIImage(systemName: "bell",
withConfiguration: UIImage.SymbolConfiguration(scale: .large)),
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
notifyButton.imageView?.contentMode = .scaleAspectFit
notifyButton.accessibilityLabel = NSLocalizedString("account.notify", comment: "")
notifyButton.tintColor = .secondaryLabel
notifyButton.isHidden = true
@ -340,7 +362,7 @@ private extension AccountHeaderView {
unnotifyButton.setImage(
UIImage(systemName: "bell.fill",
withConfiguration: UIImage.SymbolConfiguration(scale: .large)),
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
unnotifyButton.accessibilityLabel = NSLocalizedString("account.unnotify", comment: "")
unnotifyButton.isHidden = true
@ -505,7 +527,9 @@ private extension AccountHeaderView {
equalTo: headerImageView.bottomAnchor,
constant: .defaultSpacing),
relationshipButtonsStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
relationshipButtonsStackView.bottomAnchor.constraint(equalTo: avatarBackgroundView.bottomAnchor),
directMessageButton.widthAnchor.constraint(equalTo: directMessageButton.heightAnchor),
notifyButton.widthAnchor.constraint(equalTo: notifyButton.heightAnchor),
unnotifyButton.widthAnchor.constraint(equalTo: unnotifyButton.heightAnchor),
baseStackView.topAnchor.constraint(equalTo: avatarBackgroundView.bottomAnchor, constant: .defaultSpacing),
baseStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
baseStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),