Show account for request (IOS-241)

This commit is contained in:
Nathan Mattes 2024-07-10 23:03:21 +02:00
parent 7c6c9b5e79
commit 4cf75d307d
5 changed files with 175 additions and 28 deletions

View File

@ -164,6 +164,7 @@
D84BB76D2C3D88B000493718 /* DataSourceFacade+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84BB76C2C3D88B000493718 /* DataSourceFacade+Notifications.swift */; };
D84BB76F2C3D8DBC00493718 /* NotificationRequestsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84BB76E2C3D8DBC00493718 /* NotificationRequestsTableViewController.swift */; };
D84BB7722C3E566C00493718 /* NotificationPolicyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84BB7712C3E566C00493718 /* NotificationPolicyHeaderView.swift */; };
D84BB7752C3EB80900493718 /* NotificationRequestTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84BB7742C3EB80900493718 /* NotificationRequestTableViewCell.swift */; };
D84FA0932AE6915800987F47 /* MBProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = D84FA0922AE6915800987F47 /* MBProgressHUD */; };
D852C23C2AC5D02C00309232 /* AboutInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */; };
D852C23E2AC5D03300309232 /* InstanceRulesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */; };
@ -802,6 +803,7 @@
D84BB76C2C3D88B000493718 /* DataSourceFacade+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Notifications.swift"; sourceTree = "<group>"; };
D84BB76E2C3D8DBC00493718 /* NotificationRequestsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRequestsTableViewController.swift; sourceTree = "<group>"; };
D84BB7712C3E566C00493718 /* NotificationPolicyHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPolicyHeaderView.swift; sourceTree = "<group>"; };
D84BB7742C3EB80900493718 /* NotificationRequestTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRequestTableViewCell.swift; sourceTree = "<group>"; };
D84C099D2B0F9E33009E685E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
D84C099F2B0F9E41009E685E /* Setup.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Setup.md; sourceTree = "<group>"; };
D84C09A02B0F9E41009E685E /* How-it-works.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "How-it-works.md"; sourceTree = "<group>"; };
@ -1774,8 +1776,8 @@
D80EC2602C2978CB009724A5 /* Notification Filtering */ = {
isa = PBXGroup;
children = (
D84BB7732C3EB7F600493718 /* Requests */,
D84BB7702C3E565100493718 /* Policy */,
D84BB76E2C3D8DBC00493718 /* NotificationRequestsTableViewController.swift */,
);
path = "Notification Filtering";
sourceTree = "<group>";
@ -1839,6 +1841,15 @@
path = Policy;
sourceTree = "<group>";
};
D84BB7732C3EB7F600493718 /* Requests */ = {
isa = PBXGroup;
children = (
D84BB76E2C3D8DBC00493718 /* NotificationRequestsTableViewController.swift */,
D84BB7742C3EB80900493718 /* NotificationRequestTableViewCell.swift */,
);
path = Requests;
sourceTree = "<group>";
};
D84C099E2B0F9E41009E685E /* Documentation */ = {
isa = PBXGroup;
children = (
@ -3620,6 +3631,7 @@
D81A94172B07A1D30067A19D /* ProfileCardView+Configuration.swift in Sources */,
DB63F7452799056400455B82 /* HashtagTableViewCell.swift in Sources */,
D82BD7552ABC73AF009A374A /* NotificationPolicyTableViewCell.swift in Sources */,
D84BB7752C3EB80900493718 /* NotificationRequestTableViewCell.swift in Sources */,
DB0F8150264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift in Sources */,
DB98EB5327B0F9890082E365 /* ReportHeadlineTableViewCell.swift in Sources */,
DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */,

View File

@ -11,8 +11,8 @@ extension DataSourceFacade {
provider.coordinator.showLoading()
do {
let notificationRequests = try await provider.context.apiService.notificationRequests(authenticationBox: provider.authContext.mastodonAuthenticationBox)
let viewModel = NotificationRequestsViewModel()
let notificationRequests = try await provider.context.apiService.notificationRequests(authenticationBox: provider.authContext.mastodonAuthenticationBox).value
let viewModel = NotificationRequestsViewModel(requests: notificationRequests)
provider.coordinator.hideLoading()

View File

@ -1,25 +0,0 @@
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
import UIKit
struct NotificationRequestsViewModel {
}
class NotificationRequestsTableViewController: UIViewController {
let tableView: UITableView
init(viewModel: NotificationRequestsViewModel) {
//TODO: Cell, DataSource, Delegate....
tableView = UITableView(frame: .zero)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = .systemBackground
super.init(nibName: nil, bundle: nil)
view.addSubview(tableView)
tableView.pinToParent()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}

View File

@ -0,0 +1,90 @@
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
import UIKit
import MastodonSDK
import MetaTextKit
import MastodonMeta
import MastodonUI
import MastodonCore
class NotificationRequestTableViewCell: UITableViewCell {
static let reuseIdentifier = "NotificationRequestTableViewCell"
let nameLabel: MetaLabel
let usernameLabel: MetaLabel
let avatarButton: AvatarButton
private let labelStackView: UIStackView
private let contentStackView: UIStackView
// private let stack
// accept/deny-button
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
nameLabel = MetaLabel(style: .statusName)
usernameLabel = MetaLabel(style: .statusUsername)
avatarButton = AvatarButton()
avatarButton.translatesAutoresizingMaskIntoConstraints = false
avatarButton.size = CGSize.authorAvatarButtonSize
avatarButton.avatarImageView.imageViewSize = CGSize.authorAvatarButtonSize
labelStackView = UIStackView(arrangedSubviews: [nameLabel, usernameLabel])
labelStackView.axis = .vertical
labelStackView.alignment = .leading
labelStackView.spacing = 4
contentStackView = UIStackView(arrangedSubviews: [avatarButton, labelStackView])
contentStackView.translatesAutoresizingMaskIntoConstraints = false
contentStackView.axis = .horizontal
contentStackView.alignment = .center
contentStackView.spacing = 12
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(contentStackView)
setupConstraints()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupConstraints() {
let constraints = [
contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
contentView.trailingAnchor.constraint(equalTo: contentStackView.trailingAnchor, constant: 16),
contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 16),
avatarButton.widthAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.width).priority(.required - 1),
avatarButton.heightAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.height).priority(.required - 1),
]
NSLayoutConstraint.activate(constraints)
}
override func prepareForReuse() {
avatarButton.avatarImageView.image = nil
avatarButton.avatarImageView.cancelTask()
}
func configure(with request: Mastodon.Entity.NotificationRequest) {
let account = request.account
avatarButton.avatarImageView.configure(with: account.avatarImageURL())
avatarButton.avatarImageView.configure(cornerConfiguration: .init(corner: .fixed(radius: 12)))
// author name
let metaAccountName: MetaContent
do {
let content = MastodonContent(content: account.displayNameWithFallback, emojis: account.emojis.asDictionary)
metaAccountName = try MastodonMetaContent.convert(document: content)
} catch {
assertionFailure(error.localizedDescription)
metaAccountName = PlaintextMetaContent(string: account.displayNameWithFallback)
}
nameLabel.configure(content: metaAccountName)
let metaUsername = PlaintextMetaContent(string: "@\(account.acct)")
usernameLabel.configure(content: metaUsername)
}
}

View File

@ -0,0 +1,70 @@
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
import UIKit
import MastodonSDK
struct NotificationRequestsViewModel {
var requests: [Mastodon.Entity.NotificationRequest]
}
enum NotificationRequestsSection: Hashable {
case main
}
enum NotificationRequestItem: Hashable {
case item(Mastodon.Entity.NotificationRequest)
}
class NotificationRequestsTableViewController: UIViewController {
let tableView: UITableView
var viewModel: NotificationRequestsViewModel
var dataSource: UITableViewDiffableDataSource<NotificationRequestsSection, NotificationRequestItem>?
init(viewModel: NotificationRequestsViewModel) {
//TODO: DataSource, Delegate....
self.viewModel = viewModel
tableView = UITableView(frame: .zero)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = .systemBackground
tableView.register(NotificationRequestTableViewCell.self, forCellReuseIdentifier: NotificationRequestTableViewCell.reuseIdentifier)
super.init(nibName: nil, bundle: nil)
view.addSubview(tableView)
tableView.pinToParent()
let dataSource = UITableViewDiffableDataSource<NotificationRequestsSection, NotificationRequestItem>(tableView: tableView) { tableView, indexPath, itemIdentifier in
guard let cell = tableView.dequeueReusableCell(withIdentifier: NotificationRequestTableViewCell.reuseIdentifier, for: indexPath) as? NotificationRequestTableViewCell else {
fatalError("No NotificationRequestTableViewCell")
}
let request = viewModel.requests[indexPath.row]
cell.configure(with: request)
return cell
}
tableView.dataSource = dataSource
tableView.delegate = self
self.dataSource = dataSource
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
var snapshot = NSDiffableDataSourceSnapshot<NotificationRequestsSection, NotificationRequestItem>()
snapshot.appendSections([.main])
snapshot.appendItems(viewModel.requests.compactMap { NotificationRequestItem.item($0) } )
dataSource?.apply(snapshot)
}
}
extension NotificationRequestsTableViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}