Compare commits

..

No commits in common. "e6e5554edf407260a94c2932dc0b12ba07b65858" and "1fda4248ec994b2e6f7cbe8853eb58ce5adffad8" have entirely different histories.

8 changed files with 129 additions and 237 deletions

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
public class NotificationGroup: Identifiable, Hashable { public class NotificationGroup {
public let notifications: [Notification] public let notifications: [Notification]
public let id: String public let id: String
public let kind: Notification.Kind public let kind: Notification.Kind
@ -26,14 +26,6 @@ public class NotificationGroup: Identifiable, Hashable {
} }
} }
public static func ==(lhs: NotificationGroup, rhs: NotificationGroup) -> Bool {
return lhs.id == rhs.id
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func createGroups(notifications: [Notification], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] { public static func createGroups(notifications: [Notification], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] {
var groups = [[Notification]]() var groups = [[Notification]]()
for notification in notifications { for notification in notifications {
@ -58,3 +50,5 @@ public class NotificationGroup: Identifiable, Hashable {
} }
} }
extension NotificationGroup: Identifiable {}

View File

@ -73,12 +73,12 @@ class FastAccountSwitcherViewController: UIViewController {
accountView.alpha = 0 accountView.alpha = 0
accountView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2) accountView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
UIView.addKeyframe(withRelativeStartTime: relStart, relativeDuration: relDuration / 2) { UIView.addKeyframe(withRelativeStartTime: relStart, relativeDuration: relDuration) {
accountView.alpha = 1 accountView.alpha = 1
accountView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9) accountView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
} }
UIView.addKeyframe(withRelativeStartTime: relStart + relDuration / 2, relativeDuration: relDuration / 2) { UIView.addKeyframe(withRelativeStartTime: relStart + relDuration, relativeDuration: relDuration) {
accountView.transform = .identity accountView.transform = .identity
} }
} }

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
import Pachyderm import Pachyderm
class NotificationsTableViewController: DiffableTimelineLikeTableViewController<NotificationsTableViewController.Section, NotificationGroup> { class NotificationsTableViewController: TimelineLikeTableViewController<NotificationGroup> {
private let statusCell = "statusCell" private let statusCell = "statusCell"
private let actionGroupCell = "actionGroupCell" private let actionGroupCell = "actionGroupCell"
@ -54,9 +54,88 @@ class NotificationsTableViewController: DiffableTimelineLikeTableViewController<
tableView.register(UINib(nibName: "BasicTableViewCell", bundle: .main), forCellReuseIdentifier: unknownCell) tableView.register(UINib(nibName: "BasicTableViewCell", bundle: .main), forCellReuseIdentifier: unknownCell)
} }
// MARK: - DiffableTimelineLikeTableViewController override func loadInitialItems(completion: @escaping ([NotificationGroup]) -> Void) {
let request = Client.getNotifications(excludeTypes: excludedTypes)
mastodonController.run(request) { (response) in
guard case let .success(notifications, pagination) = response else {
completion([])
return
}
let groups = NotificationGroup.createGroups(notifications: notifications, only: self.groupTypes)
self.newer = pagination?.newer
self.older = pagination?.older
self.mastodonController.persistentContainer.addAll(notifications: notifications) {
completion(groups)
}
}
}
override func loadOlder(completion: @escaping ([NotificationGroup]) -> Void) {
guard let older = older else {
completion([])
return
}
let request = Client.getNotifications(excludeTypes: excludedTypes, range: older)
mastodonController.run(request) { (response) in
guard case let .success(newNotifications, pagination) = response else { fatalError() }
self.older = pagination?.older
let groups = NotificationGroup.createGroups(notifications: newNotifications, only: self.groupTypes)
self.mastodonController.persistentContainer.addAll(notifications: newNotifications) {
completion(groups)
}
}
}
override func loadNewer(completion: @escaping ([NotificationGroup]) -> Void) {
guard let newer = newer else {
completion([])
return
}
let request = Client.getNotifications(excludeTypes: excludedTypes, range: newer)
mastodonController.run(request) { (response) in
guard case let .success(newNotifications, pagination) = response else { fatalError() }
if let newer = pagination?.newer {
self.newer = newer
}
let groups = NotificationGroup.createGroups(notifications: newNotifications, only: self.groupTypes)
self.mastodonController.persistentContainer.addAll(notifications: newNotifications) {
completion(groups)
}
}
}
private func dismissNotificationsInGroup(at indexPath: IndexPath, completion: (() -> Void)? = nil) {
let group = DispatchGroup()
item(for: indexPath).notifications
.map { Pachyderm.Notification.dismiss(id: $0.id) }
.forEach { (request) in
group.enter()
mastodonController.run(request) { (_) in
group.leave()
}
}
group.notify(queue: .main) {
self.sections[indexPath.section].remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
completion?()
}
}
// MARK: - UITableViewDataSource
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let group = item(for: indexPath)
override func cellProvider(_ tableView: UITableView, _ indexPath: IndexPath, _ group: NotificationGroup) -> UITableViewCell? {
switch group.kind { switch group.kind {
case .mention: case .mention:
guard let notification = group.notifications.first, guard let notification = group.notifications.first,
@ -100,112 +179,6 @@ class NotificationsTableViewController: DiffableTimelineLikeTableViewController<
} }
} }
override func loadInitialItems(completion: @escaping (LoadResult) -> Void) {
let request = Client.getNotifications(excludeTypes: excludedTypes)
mastodonController.run(request) { (response) in
switch response {
case let .failure(error):
completion(.failure(.client(error)))
case let .success(notifications, pagination):
let groups = NotificationGroup.createGroups(notifications: notifications, only: self.groupTypes)
self.newer = pagination?.newer
self.older = pagination?.older
self.mastodonController.persistentContainer.addAll(notifications: notifications) {
var snapshot = Snapshot()
snapshot.appendSections([.notifications])
snapshot.appendItems(groups, toSection: .notifications)
completion(.success(snapshot))
}
}
}
}
override func loadOlderItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) {
guard let older = older else {
completion(.failure(.noOlder))
return
}
let request = Client.getNotifications(excludeTypes: excludedTypes, range: older)
mastodonController.run(request) { (response) in
switch response {
case let .failure(error):
completion(.failure(.client(error)))
case let .success(newNotifications, pagination):
if let older = pagination?.older {
self.older = older
}
let groups = NotificationGroup.createGroups(notifications: newNotifications, only: self.groupTypes)
self.mastodonController.persistentContainer.addAll(notifications: newNotifications) {
var snapshot = currentSnapshot()
snapshot.appendItems(groups, toSection: .notifications)
completion(.success(snapshot))
}
}
}
}
override func loadNewerItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) {
guard let newer = newer else {
completion(.failure(.noNewer))
return
}
let request = Client.getNotifications(excludeTypes: excludedTypes, range: newer)
mastodonController.run(request) { (response) in
switch response {
case let .failure(error):
completion(.failure(.client(error)))
case let .success(newNotifications, pagination):
guard !newNotifications.isEmpty else {
completion(.failure(.allCaughtUp))
return
}
if let newer = pagination?.newer {
self.newer = newer
}
let groups = NotificationGroup.createGroups(notifications: newNotifications, only: self.groupTypes)
self.mastodonController.persistentContainer.addAll(notifications: newNotifications) {
var snapshot = currentSnapshot()
if let first = snapshot.itemIdentifiers(inSection: .notifications).first {
snapshot.insertItems(groups, beforeItem: first)
} else {
snapshot.appendItems(groups, toSection: .notifications)
}
completion(.success(snapshot))
}
}
}
}
private func dismissNotificationsInGroup(at indexPath: IndexPath, completion: (() -> Void)? = nil) {
guard let item = dataSource.itemIdentifier(for: indexPath) else { return }
let group = DispatchGroup()
item.notifications
.map { Pachyderm.Notification.dismiss(id: $0.id) }
.forEach { (request) in
group.enter()
mastodonController.run(request) { (_) in
group.leave()
}
}
group.notify(queue: .main) {
var snapshot = self.dataSource.snapshot()
snapshot.deleteItems([item])
self.dataSource.apply(snapshot, completion: completion)
}
}
// MARK: - UITableViewDelegate // MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
@ -238,12 +211,6 @@ class NotificationsTableViewController: DiffableTimelineLikeTableViewController<
} }
} }
extension NotificationsTableViewController {
enum Section: CaseIterable, Hashable {
case notifications
}
}
extension NotificationsTableViewController: TuskerNavigationDelegate { extension NotificationsTableViewController: TuskerNavigationDelegate {
var apiController: MastodonController { mastodonController } var apiController: MastodonController { mastodonController }
} }
@ -257,8 +224,7 @@ extension NotificationsTableViewController: StatusTableViewCellDelegate {
extension NotificationsTableViewController: UITableViewDataSourcePrefetching { extension NotificationsTableViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths { for indexPath in indexPaths {
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue } for notification in item(for: indexPath).notifications {
for notification in group.notifications {
ImageCache.avatars.fetchIfNotCached(notification.account.avatar) ImageCache.avatars.fetchIfNotCached(notification.account.avatar)
} }
} }
@ -266,8 +232,7 @@ extension NotificationsTableViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths { for indexPath in indexPaths {
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue } for notification in item(for: indexPath).notifications {
for notification in group.notifications {
ImageCache.avatars.cancelWithoutCallback(notification.account.avatar) ImageCache.avatars.cancelWithoutCallback(notification.account.avatar)
} }
} }

View File

@ -168,7 +168,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
} }
} }
override func loadOlderItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) { override func loadOlderItems(currentSnapshot: Snapshot, completion: @escaping (LoadResult) -> Void) {
guard let older = older else { guard let older = older else {
completion(.failure(.noOlder)) completion(.failure(.noOlder))
return return
@ -176,12 +176,12 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
if #available(iOS 15.0, *), if #available(iOS 15.0, *),
Preferences.shared.disableInfiniteScrolling && !didConfirmLoadMore { Preferences.shared.disableInfiniteScrolling && !didConfirmLoadMore {
var snapshot = currentSnapshot() guard !currentSnapshot.itemIdentifiers(inSection: .footer).contains(.confirmLoadMore) else {
guard !snapshot.itemIdentifiers(inSection: .footer).contains(.confirmLoadMore) else {
// todo: need something more accurate than "success"/"failure" // todo: need something more accurate than "success"/"failure"
completion(.success(snapshot)) completion(.success(currentSnapshot))
return return
} }
var snapshot = currentSnapshot
snapshot.appendItems([.confirmLoadMore], toSection: .footer) snapshot.appendItems([.confirmLoadMore], toSection: .footer)
self.dataSource.apply(snapshot) self.dataSource.apply(snapshot)
completion(.success(snapshot)) completion(.success(snapshot))
@ -199,7 +199,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
self.older = pagination?.older self.older = pagination?.older
self.mastodonController.persistentContainer.addAll(statuses: statuses) { self.mastodonController.persistentContainer.addAll(statuses: statuses) {
var snapshot = currentSnapshot() var snapshot = currentSnapshot
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) }, toSection: .statuses) snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) }, toSection: .statuses)
snapshot.deleteItems([.confirmLoadMore]) snapshot.deleteItems([.confirmLoadMore])
completion(.success(snapshot)) completion(.success(snapshot))
@ -208,7 +208,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
} }
} }
override func loadNewerItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) { override func loadNewerItems(currentSnapshot: Snapshot, completion: @escaping (LoadResult) -> Void) {
guard let newer = newer else { guard let newer = newer else {
completion(.failure(.noNewer)) completion(.failure(.noNewer))
return return
@ -221,11 +221,6 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
completion(.failure(.client(error))) completion(.failure(.client(error)))
case let .success(statuses, pagination): case let .success(statuses, pagination):
guard !statuses.isEmpty else {
completion(.failure(.allCaughtUp))
return
}
// if there are no new statuses, pagination is nil // if there are no new statuses, pagination is nil
// if we were to then overwrite self.newer, future refresh would fail // if we were to then overwrite self.newer, future refresh would fail
if let newer = pagination?.newer { if let newer = pagination?.newer {
@ -233,7 +228,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
} }
self.mastodonController.persistentContainer.addAll(statuses: statuses) { self.mastodonController.persistentContainer.addAll(statuses: statuses) {
var snapshot = currentSnapshot() var snapshot = currentSnapshot
let newIdentifiers = statuses.map { Item.status(id: $0.id, state: .unknown) } let newIdentifiers = statuses.map { Item.status(id: $0.id, state: .unknown) }
if let first = snapshot.itemIdentifiers(inSection: .statuses).first { if let first = snapshot.itemIdentifiers(inSection: .statuses).first {
snapshot.insertItems(newIdentifiers, beforeItem: first) snapshot.insertItems(newIdentifiers, beforeItem: first)

View File

@ -146,7 +146,7 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
state = .loadingOlder state = .loadingOlder
loadOlderItems(currentSnapshot: dataSource.snapshot) { result in loadOlderItems(currentSnapshot: dataSource.snapshot()) { result in
DispatchQueue.main.async { DispatchQueue.main.async {
self.state = .loaded self.state = .loaded
@ -212,22 +212,18 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
state = .loadingNewer state = .loadingNewer
var firstItem: Item? = nil let snapshot = dataSource.snapshot()
let currentSnapshot: () -> Snapshot = {
let snapshot = self.dataSource.snapshot()
for section in self.timelineContentSections() { var item: Item? = nil
if snapshot.indexOfSection(section) != nil, for section in timelineContentSections() {
let first = snapshot.itemIdentifiers(inSection: section).first { if snapshot.indexOfSection(section) != nil,
firstItem = first let first = snapshot.itemIdentifiers(inSection: section).first {
break item = first
} break
} }
return snapshot
} }
loadNewerItems(currentSnapshot: currentSnapshot) { result in loadNewerItems(currentSnapshot: snapshot) { result in
DispatchQueue.main.async { DispatchQueue.main.async {
self.refreshControl?.endRefreshing() self.refreshControl?.endRefreshing()
self.state = .loaded self.state = .loaded
@ -235,8 +231,8 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
switch result { switch result {
case let .success(snapshot): case let .success(snapshot):
self.dataSource.apply(snapshot, animatingDifferences: false) self.dataSource.apply(snapshot, animatingDifferences: false)
if let firstItem = firstItem, if let item = item,
let indexPath = self.dataSource.indexPath(for: firstItem) { let indexPath = self.dataSource.indexPath(for: item) {
// maintain the current position in the list (don't scroll to top) // maintain the current position in the list (don't scroll to top)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
} }
@ -252,15 +248,6 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
} }
self.showToast(configuration: config, animated: true) self.showToast(configuration: config, animated: true)
case .failure(.allCaughtUp):
var config = ToastConfiguration(title: "You're all caught up")
config.edge = .top
config.dismissAutomaticallyAfter = 2
config.action = { (toast) in
toast.dismissToast(animated: true)
}
self.showToast(configuration: config, animated: true)
default: default:
break break
} }
@ -278,11 +265,11 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
fatalError("loadInitialItems(completion:) must be implemented by subclasses") fatalError("loadInitialItems(completion:) must be implemented by subclasses")
} }
func loadOlderItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) { func loadOlderItems(currentSnapshot: Snapshot, completion: @escaping (LoadResult) -> Void) {
fatalError("loadOlderItesm(completion:) must be implemented by subclasses") fatalError("loadOlderItesm(completion:) must be implemented by subclasses")
} }
func loadNewerItems(currentSnapshot: @escaping () -> Snapshot, completion: @escaping (LoadResult) -> Void) { func loadNewerItems(currentSnapshot: Snapshot, completion: @escaping (LoadResult) -> Void) {
fatalError("loadNewerItems(completion:) must be implemented by subclasses") fatalError("loadNewerItems(completion:) must be implemented by subclasses")
} }
@ -310,7 +297,6 @@ extension DiffableTimelineLikeTableViewController {
case noClient case noClient
case noOlder case noOlder
case noNewer case noNewer
case allCaughtUp
case client(Client.Error) case client(Client.Error)
} }
} }

View File

@ -10,7 +10,6 @@ import UIKit
struct ToastConfiguration { struct ToastConfiguration {
var systemImageName: String? var systemImageName: String?
var titleFont: UIFont = .boldSystemFont(ofSize: 14)
var title: String var title: String
var subtitle: String? var subtitle: String?
var actionTitle: String? var actionTitle: String?
@ -18,7 +17,6 @@ struct ToastConfiguration {
var edgeSpacing: CGFloat = 8 var edgeSpacing: CGFloat = 8
var edge: Edge = .automatic var edge: Edge = .automatic
var dismissOnScroll = true var dismissOnScroll = true
var dismissAutomaticallyAfter: TimeInterval? = nil
init(title: String) { init(title: String) {
self.title = title self.title = title

View File

@ -14,8 +14,6 @@ class ToastView: UIView {
private var shrinkAnimator: UIViewPropertyAnimator? private var shrinkAnimator: UIViewPropertyAnimator?
private var recognizedGesture = false private var recognizedGesture = false
private var shouldDismissOnScroll = false
private(set) var shouldDismissAutomatically = true
private var offscreenTranslation: CGFloat { private var offscreenTranslation: CGFloat {
var translation = bounds.height + configuration.edgeSpacing var translation = bounds.height + configuration.edgeSpacing
@ -64,7 +62,7 @@ class ToastView: UIView {
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.text = configuration.title titleLabel.text = configuration.title
titleLabel.textColor = .white titleLabel.textColor = .white
titleLabel.font = configuration.titleFont titleLabel.font = .boldSystemFont(ofSize: 14)
titleLabel.adjustsFontSizeToFitWidth = true titleLabel.adjustsFontSizeToFitWidth = true
if let subtitle = configuration.subtitle { if let subtitle = configuration.subtitle {
@ -111,40 +109,10 @@ class ToastView: UIView {
layer.shadowPath = CGPath(roundedRect: bounds, cornerWidth: layer.cornerRadius, cornerHeight: layer.cornerRadius, transform: nil) layer.shadowPath = CGPath(roundedRect: bounds, cornerWidth: layer.cornerRadius, cornerHeight: layer.cornerRadius, transform: nil)
} }
func dismissToast(animated: Bool) {
guard animated else {
removeFromSuperview()
return
}
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseInOut) {
self.transform = CGAffineTransform(translationX: 0, y: self.offscreenTranslation)
} completion: { (_) in
self.removeFromSuperview()
}
}
func animateAppearance() {
self.transform = CGAffineTransform(translationX: 0, y: offscreenTranslation)
let duration = 0.5
let velocity = 0.5
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: velocity, options: []) {
self.transform = .identity
}
}
func setupDismissOnScroll(connectedTo scrollView: UIScrollView) {
guard configuration.dismissOnScroll else { return }
scrollView.panGestureRecognizer.addTarget(self, action: #selector(scrollViewPanGestureRecognized))
}
// MARK: - Interaction
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) super.touchesBegan(touches, with: event)
recognizedGesture = false recognizedGesture = false
shouldDismissAutomatically = false
shrinkAnimator = UIViewPropertyAnimator(duration: 0.1, curve: .easeInOut) { shrinkAnimator = UIViewPropertyAnimator(duration: 0.1, curve: .easeInOut) {
self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95) self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
} }
@ -177,7 +145,6 @@ class ToastView: UIView {
switch recognizer.state { switch recognizer.state {
case .began: case .began:
recognizedGesture = true recognizedGesture = true
shouldDismissAutomatically = false
UIView.animate(withDuration: 0.1, delay: 0, options: [.curveEaseInOut, .allowUserInteraction]) { UIView.animate(withDuration: 0.1, delay: 0, options: [.curveEaseInOut, .allowUserInteraction]) {
self.transform = .identity self.transform = .identity
} }
@ -232,23 +199,24 @@ class ToastView: UIView {
} }
} }
@objc private func scrollViewPanGestureRecognized(_ recognizer: UIPanGestureRecognizer) { func dismissToast(animated: Bool) {
switch recognizer.state { guard animated else {
case .began: removeFromSuperview()
shouldDismissOnScroll = true return
}
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseInOut) {
self.transform = CGAffineTransform(translationX: 0, y: self.offscreenTranslation)
} completion: { (_) in
self.removeFromSuperview()
}
}
case .changed: func animateAppearance() {
let translation = recognizer.translation(in: recognizer.view).y self.transform = CGAffineTransform(translationX: 0, y: offscreenTranslation)
if shouldDismissOnScroll && abs(translation) > 50 { let duration = 0.5
dismissToast(animated: true) let velocity = 0.5
shouldDismissOnScroll = false UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: velocity, options: []) {
} self.transform = .identity
case .ended, .cancelled:
shouldDismissOnScroll = false
default:
break
} }
} }

View File

@ -11,7 +11,6 @@ import UIKit
protocol ToastableViewController: UIViewController { protocol ToastableViewController: UIViewController {
var toastParentView: UIView { get } var toastParentView: UIView { get }
var toastScrollView: UIScrollView? { get }
} }
@ -34,7 +33,6 @@ extension ToastableViewController {
} }
var toastParentView: UIView { view } var toastParentView: UIView { view }
var toastScrollView: UIScrollView? { view as? UIScrollView }
func showToast(configuration config: ToastConfiguration, animated: Bool) { func showToast(configuration config: ToastConfiguration, animated: Bool) {
currentToast?.dismissToast(animated: false) currentToast?.dismissToast(animated: false)
@ -69,18 +67,6 @@ extension ToastableViewController {
if animated { if animated {
toast.animateAppearance() toast.animateAppearance()
} }
if config.dismissOnScroll,
let scrollView = toastScrollView {
toast.setupDismissOnScroll(connectedTo: scrollView)
}
if let time = config.dismissAutomaticallyAfter {
DispatchQueue.main.asyncAfter(deadline: .now() + time) { [weak toast] in
guard let toast = toast, toast.shouldDismissAutomatically else { return }
toast.dismissToast(animated: true)
}
}
} }
private func effectiveEdge(edge: ToastConfiguration.Edge) -> ToastConfiguration.Edge { private func effectiveEdge(edge: ToastConfiguration.Edge) -> ToastConfiguration.Edge {