2
2
mirror of https://github.com/mastodon/mastodon-ios synced 2025-04-11 22:58:02 +02:00

Add basic UI filter notification-filtering-setting (IOS-241)

This commit is contained in:
Nathan Mattes 2024-07-08 11:38:57 +02:00
parent 4843348034
commit 151880f661
3 changed files with 176 additions and 2 deletions

View File

@ -160,6 +160,7 @@
D8363B1629469CE200A74079 /* OnboardingNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8363B1529469CE200A74079 /* OnboardingNextView.swift */; };
D83B54F82C2AC2FA00D18A7B /* NotificationFilteringBannerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83B54F72C2AC2FA00D18A7B /* NotificationFilteringBannerTableViewCell.swift */; };
D84738D42BBD9ABE00ECD52B /* TimelineStatusPill.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84738D32BBD9ABE00ECD52B /* TimelineStatusPill.swift */; };
D84BB76B2C3BE33800493718 /* NotificationPolicyFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84BB76A2C3BE33800493718 /* NotificationPolicyFilterTableViewCell.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 */; };
@ -794,6 +795,7 @@
D8363B1529469CE200A74079 /* OnboardingNextView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = OnboardingNextView.swift; sourceTree = "<group>"; tabWidth = 4; };
D83B54F72C2AC2FA00D18A7B /* NotificationFilteringBannerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFilteringBannerTableViewCell.swift; sourceTree = "<group>"; };
D84738D32BBD9ABE00ECD52B /* TimelineStatusPill.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStatusPill.swift; sourceTree = "<group>"; };
D84BB76A2C3BE33800493718 /* NotificationPolicyFilterTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPolicyFilterTableViewCell.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>"; };
@ -1767,6 +1769,7 @@
isa = PBXGroup;
children = (
D80EC2622C2978EE009724A5 /* NotificationPolicyViewController.swift */,
D84BB76A2C3BE33800493718 /* NotificationPolicyFilterTableViewCell.swift */,
);
path = "Notification Filtering";
sourceTree = "<group>";
@ -3559,6 +3562,7 @@
DBA9443E265CFA6400C537E1 /* ProfileFieldCollectionViewCell.swift in Sources */,
2D24E1232626ED9D00A59D4F /* UIView+Gesture.swift in Sources */,
DBFEEC9D279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift in Sources */,
D84BB76B2C3BE33800493718 /* NotificationPolicyFilterTableViewCell.swift in Sources */,
DB3E6FEC2806D7F100B035AE /* DiscoveryNewsViewController.swift in Sources */,
DBCBED1726132DB500B49291 /* UserTimelineViewModel+Diffable.swift in Sources */,
D8FAAE412AD0475900DC1832 /* AboutInstanceTableViewHeader.swift in Sources */,

View File

@ -0,0 +1,49 @@
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
import UIKit
protocol NotificationPolicyFilterTableViewCellDelegate: AnyObject {
func toggleValueChanged(_ tableViewCell: NotificationPolicyFilterTableViewCell, filterItem: NotificationFilterItem, newValue: Bool)
}
class NotificationPolicyFilterTableViewCell: ToggleTableViewCell {
override class var reuseIdentifier: String {
return "NotificationPolicyFilterTableViewCell"
}
var filterItem: NotificationFilterItem?
weak var delegate: NotificationPolicyFilterTableViewCellDelegate?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
toggle.addTarget(self, action: #selector(NotificationPolicyFilterTableViewCell.toggleValueChanged(_:)), for: .valueChanged)
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
public func configure(with filterItem: NotificationFilterItem, viewModel: NotificationFilterViewModel) {
label.text = filterItem.title
self.filterItem = filterItem
let toggleIsOn: Bool
switch filterItem {
case .notFollowing:
toggleIsOn = viewModel.notFollowing
case .noFollower:
toggleIsOn = viewModel.noFollower
case .newAccount:
toggleIsOn = viewModel.newAccount
case .privateMentions:
toggleIsOn = viewModel.privateMentions
}
toggle.isOn = toggleIsOn
}
@objc func toggleValueChanged(_ sender: UISwitch) {
guard let filterItem, let delegate else { return }
delegate.toggleValueChanged(self, filterItem: filterItem, newValue: sender.isOn)
}
}

View File

@ -1,13 +1,134 @@
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
import UIKit
import MastodonLocalization
enum NotificationFilterSection: Hashable {
case main
}
enum NotificationFilterItem: Hashable, CaseIterable {
case notFollowing
case noFollower
case newAccount
case privateMentions
var title: String {
switch self {
case .notFollowing:
return "People you don't follow"
case .noFollower:
return "People not following you"
case .newAccount:
return "New accounts"
case .privateMentions:
return "Unsolicited private mentions"
}
}
}
struct NotificationFilterViewModel {
var notFollowing: Bool
var noFollower: Bool
var newAccount: Bool
var privateMentions: Bool
init(notFollowing: Bool, noFollower: Bool, newAccount: Bool, privateMentions: Bool) {
self.notFollowing = notFollowing
self.noFollower = noFollower
self.newAccount = newAccount
self.privateMentions = privateMentions
}
}
class NotificationPolicyViewController: UIViewController {
//TODO: DataSource, Source, Items
let tableView: UITableView
var dataSource: UITableViewDiffableDataSource<NotificationFilterSection, NotificationFilterItem>?
let items: [NotificationFilterItem]
let viewModel: NotificationFilterViewModel
init() {
//TODO: Dependency Inject Policy ViewModel
viewModel = NotificationFilterViewModel(notFollowing: false, noFollower: false, newAccount: false, privateMentions: false)
items = NotificationFilterItem.allCases
tableView = UITableView(frame: .zero, style: .insetGrouped)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.register(NotificationPolicyFilterTableViewCell.self, forCellReuseIdentifier: NotificationPolicyFilterTableViewCell.reuseIdentifier)
super.init(nibName: nil, bundle: nil)
view.backgroundColor = .systemGreen
let dataSource = UITableViewDiffableDataSource<NotificationFilterSection, NotificationFilterItem>(tableView: tableView) { [weak self] tableView, indexPath, itemIdentifier in
guard let self, let cell = tableView.dequeueReusableCell(withIdentifier: NotificationPolicyFilterTableViewCell.reuseIdentifier, for: indexPath) as? NotificationPolicyFilterTableViewCell else {
fatalError("No NotificationPolicyFilterTableViewCell")
}
//TODO: Configuration
let item = items[indexPath.row]
cell.configure(with: item, viewModel: self.viewModel)
cell.delegate = self
return cell
}
tableView.dataSource = dataSource
tableView.delegate = self
self.dataSource = dataSource
view.addSubview(tableView)
view.backgroundColor = .systemGroupedBackground
navigationItem.rightBarButtonItem = UIBarButtonItem(title: L10n.Common.Controls.Actions.save, style: .done, target: self, action: #selector(NotificationPolicyViewController.save(_:)))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: L10n.Common.Controls.Actions.cancel, style: .done, target: self, action: #selector(NotificationPolicyViewController.cancel(_:)))
setupConstraints()
}
override func viewDidLoad() {
super.viewDidLoad()
var snapshot = NSDiffableDataSourceSnapshot<NotificationFilterSection, NotificationFilterItem>()
snapshot.appendSections([.main])
snapshot.appendItems(items)
dataSource?.apply(snapshot, animatingDifferences: false)
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupConstraints() {
let constraints = [
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
]
NSLayoutConstraint.activate(constraints)
}
// MARK: - Action
@objc private func save(_ sender: UIBarButtonItem) {
//TODO: Save
}
@objc private func cancel(_ sender: UIBarButtonItem) {
dismiss(animated: true)
}
}
extension NotificationPolicyViewController: UITableViewDelegate {
}
extension NotificationPolicyViewController: NotificationPolicyFilterTableViewCellDelegate {
func toggleValueChanged(_ tableViewCell: NotificationPolicyFilterTableViewCell, filterItem: NotificationFilterItem, newValue: Bool) {
//TODO: Update ViewModel
}
}