Add toggle to control whether Notifications tab shows all or just mentions
Closes #45
This commit is contained in:
parent
d52875cf25
commit
8bb6e9403d
|
@ -246,8 +246,10 @@ public class Client {
|
|||
}
|
||||
|
||||
// MARK: - Notifications
|
||||
public func getNotifications(range: RequestRange = .default) -> Request<[Notification]> {
|
||||
var request = Request<[Notification]>(method: .get, path: "/api/v1/notifications")
|
||||
public func getNotifications(excludeTypes: [Notification.Kind], range: RequestRange = .default) -> Request<[Notification]> {
|
||||
var request = Request<[Notification]>(method: .get, path: "/api/v1/notifications", queryParameters:
|
||||
"exclude_types" => excludeTypes.map { $0.rawValue }
|
||||
)
|
||||
request.range = range
|
||||
return request
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class Notification: Decodable {
|
|||
}
|
||||
|
||||
extension Notification {
|
||||
public enum Kind: String, Decodable {
|
||||
public enum Kind: String, Decodable, CaseIterable {
|
||||
case mention
|
||||
case reblog
|
||||
case favourite
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
D68632AA21ED8319008C716E /* GMGridViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D686329021ED8319008C716E /* GMGridViewController.m */; };
|
||||
D68632AB21ED8319008C716E /* GMImagePickerController.h in Headers */ = {isa = PBXBuildFile; fileRef = D686329121ED8319008C716E /* GMImagePickerController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D68632AC21ED8319008C716E /* GMImagePicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = D686329321ED8319008C716E /* GMImagePicker.strings */; };
|
||||
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */; };
|
||||
D6A3BC7723218E1300FD64D5 /* TimelineSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */; };
|
||||
D6A3BC7923218E9200FD64D5 /* NotificationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */; };
|
||||
D6A3BC7C232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */; };
|
||||
|
@ -165,6 +166,7 @@
|
|||
D6BC874521961F73006163F1 /* Gifu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BC874421961F73006163F1 /* Gifu.framework */; };
|
||||
D6BC874621961F73006163F1 /* Gifu.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BC874421961F73006163F1 /* Gifu.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
D6BC8748219738E1006163F1 /* EnhancedTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */; };
|
||||
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DB0232C61BC002CA326 /* NotificationsPageViewController.swift */; };
|
||||
D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */; };
|
||||
D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; };
|
||||
|
@ -389,6 +391,7 @@
|
|||
D686329021ED8319008C716E /* GMGridViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMGridViewController.m; sourceTree = "<group>"; };
|
||||
D686329121ED8319008C716E /* GMImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GMImagePickerController.h; sourceTree = "<group>"; };
|
||||
D686329421ED8319008C716E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = GMImagePicker.strings; sourceTree = "<group>"; };
|
||||
D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedPageViewController.swift; sourceTree = "<group>"; };
|
||||
D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSegment.swift; sourceTree = "<group>"; };
|
||||
D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationGroup.swift; sourceTree = "<group>"; };
|
||||
D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNotificationGroupTableViewCell.swift; sourceTree = "<group>"; };
|
||||
|
@ -410,6 +413,7 @@
|
|||
D6B8DB332182A59300424AF7 /* UIAlertController+Visibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Visibility.swift"; sourceTree = "<group>"; };
|
||||
D6BC874421961F73006163F1 /* Gifu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Gifu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedTableViewController.swift; sourceTree = "<group>"; };
|
||||
D6BC9DB0232C61BC002CA326 /* NotificationsPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsPageViewController.swift; sourceTree = "<group>"; };
|
||||
D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = "<group>"; };
|
||||
|
@ -736,6 +740,7 @@
|
|||
D641C786213DD852004B4513 /* Notifications */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6BC9DB0232C61BC002CA326 /* NotificationsPageViewController.swift */,
|
||||
D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */,
|
||||
);
|
||||
path = Notifications;
|
||||
|
@ -1029,6 +1034,7 @@
|
|||
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */,
|
||||
D6B8DB332182A59300424AF7 /* UIAlertController+Visibility.swift */,
|
||||
D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */,
|
||||
D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1491,10 +1497,12 @@
|
|||
D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */,
|
||||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
||||
D6AEBB412321642700E5038B /* SendMesasgeActivity.swift in Sources */,
|
||||
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */,
|
||||
D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */,
|
||||
D6D58DF922074B74009C8DD9 /* LinkLabel.swift in Sources */,
|
||||
0454DDAF22B462EF00B8BB8E /* GalleryExpandAnimationController.swift in Sources */,
|
||||
D6A3BC8A2321F79B00FD64D5 /* AccountTableViewCell.swift in Sources */,
|
||||
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */,
|
||||
0450531F22B0097E00100BA2 /* Timline+UI.swift in Sources */,
|
||||
D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */,
|
||||
D6C7D27D22B6EBF800071952 /* AttachmentsContainerView.swift in Sources */,
|
||||
|
|
|
@ -17,7 +17,7 @@ class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
|
|||
|
||||
viewControllers = [
|
||||
embedInNavigationController(TimelineTableViewController(for: .home)),
|
||||
embedInNavigationController(NotificationsTableViewController()),
|
||||
embedInNavigationController(NotificationsPageViewController()),
|
||||
ComposeViewController(),
|
||||
embedInNavigationController(TimelineTableViewController(for: .public(local: false))),
|
||||
embedInNavigationController(MyProfileTableViewController()),
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// NotificationsPageViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class NotificationsPageViewController: SegmentedPageViewController {
|
||||
|
||||
private let notificationsTitle = NSLocalizedString("Notifications", comment: "notifications tab title")
|
||||
private let mentionsTitle = NSLocalizedString("Mentions", comment: "mentions tab title")
|
||||
|
||||
init() {
|
||||
let notifications = NotificationsTableViewController(allowedTypes: Pachyderm.Notification.Kind.allCases)
|
||||
notifications.title = notificationsTitle
|
||||
|
||||
let mentions = NotificationsTableViewController(allowedTypes: [.mention])
|
||||
mentions.title = mentionsTitle
|
||||
|
||||
super.init(titles: [
|
||||
notificationsTitle,
|
||||
mentionsTitle
|
||||
], pageControllers: [
|
||||
notifications,
|
||||
mentions
|
||||
])
|
||||
|
||||
title = notificationsTitle
|
||||
tabBarItem.image = UIImage(systemName: "bell.fill")
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
|||
private let actionGroupCell = "actionGroupCell"
|
||||
private let followGroupCell = "followGroupCell"
|
||||
|
||||
let excludedTypes: [Pachyderm.Notification.Kind]
|
||||
let groupTypes = [Notification.Kind.favourite, .reblog, .follow]
|
||||
|
||||
var groups: [NotificationGroup] = [] {
|
||||
|
@ -28,11 +29,10 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
|||
var newer: RequestRange?
|
||||
var older: RequestRange?
|
||||
|
||||
init() {
|
||||
super.init(style: .plain)
|
||||
init(allowedTypes: [Pachyderm.Notification.Kind]) {
|
||||
self.excludedTypes = Array(Set(Pachyderm.Notification.Kind.allCases).subtracting(allowedTypes))
|
||||
|
||||
title = "Notifications"
|
||||
tabBarItem.image = UIImage(systemName: "bell.fill")
|
||||
super.init(style: .plain)
|
||||
|
||||
self.refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshNotifications(_:)), for: .valueChanged)
|
||||
|
@ -54,7 +54,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
|||
|
||||
tableView.prefetchDataSource = self
|
||||
|
||||
let request = MastodonController.client.getNotifications()
|
||||
let request = MastodonController.client.getNotifications(excludeTypes: excludedTypes)
|
||||
MastodonController.client.run(request) { result in
|
||||
guard case let .success(notifications, pagination) = result else { fatalError() }
|
||||
|
||||
|
@ -116,7 +116,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
|||
if indexPath.row == groups.count - 1 {
|
||||
guard let older = older else { return }
|
||||
|
||||
let request = MastodonController.client.getNotifications(range: older)
|
||||
let request = MastodonController.client.getNotifications(excludeTypes: excludedTypes, range: older)
|
||||
MastodonController.client.run(request) { result in
|
||||
guard case let .success(newNotifications, pagination) = result else { fatalError() }
|
||||
|
||||
|
@ -148,7 +148,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
|||
@objc func refreshNotifications(_ sender: Any) {
|
||||
guard let newer = newer else { return }
|
||||
|
||||
let request = MastodonController.client.getNotifications(range: newer)
|
||||
let request = MastodonController.client.getNotifications(excludeTypes: excludedTypes, range: newer)
|
||||
MastodonController.client.run(request) { result in
|
||||
guard case let .success(newNotifications, pagination) = result else { fatalError() }
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// SegmentedPageViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SegmentedPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
|
||||
|
||||
let titles: [String]
|
||||
let pageControllers: [UIViewController]
|
||||
|
||||
private(set) var currentIndex: Int!
|
||||
|
||||
var segmentedControl: UISegmentedControl!
|
||||
|
||||
init(titles: [String], pageControllers: [UIViewController]) {
|
||||
self.titles = titles
|
||||
self.pageControllers = pageControllers
|
||||
|
||||
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
|
||||
|
||||
self.dataSource = self
|
||||
self.delegate = self
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = .systemBackground
|
||||
|
||||
segmentedControl = UISegmentedControl(items: titles)
|
||||
segmentedControl.addTarget(self, action: #selector(segmentedControlChanged), for: .valueChanged)
|
||||
navigationItem.titleView = segmentedControl
|
||||
|
||||
segmentedControl.selectedSegmentIndex = 0
|
||||
selectPage(at: 0, animated: false)
|
||||
}
|
||||
|
||||
func selectPage(at index: Int, animated: Bool) {
|
||||
let direction: UIPageViewController.NavigationDirection = currentIndex == nil ? .forward : index - currentIndex > 0 ? .forward : .reverse
|
||||
setViewControllers([pageControllers[index]], direction: direction, animated: animated)
|
||||
navigationItem.title = pageControllers[index].title
|
||||
currentIndex = index
|
||||
}
|
||||
|
||||
@objc func segmentedControlChanged() {
|
||||
selectPage(at: segmentedControl.selectedSegmentIndex, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Page View Controller Data Source
|
||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||
guard let index = pageControllers.firstIndex(of: viewController),
|
||||
index > 0 else { return nil }
|
||||
return pageControllers[index - 1]
|
||||
}
|
||||
|
||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||
guard let index = pageControllers.firstIndex(of: viewController),
|
||||
index < pageControllers.count - 1 else { return nil }
|
||||
return pageControllers[index + 1]
|
||||
}
|
||||
|
||||
// MARK: - Page View Controller Delegate
|
||||
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
|
||||
currentIndex = pageControllers.firstIndex(of: viewControllers!.first!)!
|
||||
segmentedControl.selectedSegmentIndex = currentIndex
|
||||
navigationItem.title = viewControllers!.first!.title
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue