mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-22 08:10:59 +00:00
Mentions tab
This commit is contained in:
parent
32a019f8d7
commit
195f2d6a29
11 changed files with 156 additions and 31 deletions
|
@ -575,10 +575,12 @@ public extension ContentDatabase {
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func notificationsPublisher() -> AnyPublisher<[CollectionSection], Error> {
|
func notificationsPublisher(
|
||||||
|
excludeTypes: Set<MastodonNotification.NotificationType>) -> AnyPublisher<[CollectionSection], Error> {
|
||||||
ValueObservation.tracking(
|
ValueObservation.tracking(
|
||||||
NotificationInfo.request(
|
NotificationInfo.request(
|
||||||
NotificationRecord.order(NotificationRecord.Columns.id.desc)).fetchAll)
|
NotificationRecord.order(NotificationRecord.Columns.id.desc)
|
||||||
|
.filter(!excludeTypes.map(\.rawValue).contains(NotificationRecord.Columns.type))).fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseWriter)
|
.publisher(in: databaseWriter)
|
||||||
.map { [.init(items: $0.map {
|
.map { [.init(items: $0.map {
|
||||||
|
|
|
@ -92,6 +92,8 @@
|
||||||
"main-navigation.explore" = "Explore";
|
"main-navigation.explore" = "Explore";
|
||||||
"main-navigation.notifications" = "Notifications";
|
"main-navigation.notifications" = "Notifications";
|
||||||
"main-navigation.conversations" = "Messages";
|
"main-navigation.conversations" = "Messages";
|
||||||
|
"notifications.all" = "All";
|
||||||
|
"notifications.mentions" = "Mentions";
|
||||||
"ok" = "OK";
|
"ok" = "OK";
|
||||||
"pending.pending-confirmation" = "Your account is pending confirmation";
|
"pending.pending-confirmation" = "Your account is pending confirmation";
|
||||||
"post" = "Post";
|
"post" = "Post";
|
||||||
|
|
|
@ -26,6 +26,7 @@ public extension MastodonNotification {
|
||||||
case favourite
|
case favourite
|
||||||
case poll
|
case poll
|
||||||
case followRequest = "follow_request"
|
case followRequest = "follow_request"
|
||||||
|
case status
|
||||||
case unknown
|
case unknown
|
||||||
|
|
||||||
public static var unknownCase: Self { .unknown }
|
public static var unknownCase: Self { .unknown }
|
||||||
|
|
|
@ -5,7 +5,7 @@ import HTTP
|
||||||
import Mastodon
|
import Mastodon
|
||||||
|
|
||||||
public enum NotificationsEndpoint {
|
public enum NotificationsEndpoint {
|
||||||
case notifications
|
case notifications(excludeTypes: Set<MastodonNotification.NotificationType>)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NotificationsEndpoint: Endpoint {
|
extension NotificationsEndpoint: Endpoint {
|
||||||
|
@ -15,6 +15,13 @@ extension NotificationsEndpoint: Endpoint {
|
||||||
["notifications"]
|
["notifications"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var queryParameters: [URLQueryItem] {
|
||||||
|
switch self {
|
||||||
|
case let .notifications(excludeTypes):
|
||||||
|
return Array(excludeTypes).map { URLQueryItem(name: "exclude_types[]", value: $0.rawValue) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public var method: HTTPMethod {
|
public var method: HTTPMethod {
|
||||||
switch self {
|
switch self {
|
||||||
case .notifications:
|
case .notifications:
|
||||||
|
|
|
@ -96,6 +96,7 @@
|
||||||
D08E52EF257D757100FA2C5F /* CompositionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08E52ED257D757100FA2C5F /* CompositionView.swift */; };
|
D08E52EF257D757100FA2C5F /* CompositionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08E52ED257D757100FA2C5F /* CompositionView.swift */; };
|
||||||
D08E52F8257D78BE00FA2C5F /* ViewConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EA59472522B8B600804347 /* ViewConstants.swift */; };
|
D08E52F8257D78BE00FA2C5F /* ViewConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EA59472522B8B600804347 /* ViewConstants.swift */; };
|
||||||
D097F41B25BE3E1A00859F2C /* SearchScope+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D097F41A25BE3E1A00859F2C /* SearchScope+Extensions.swift */; };
|
D097F41B25BE3E1A00859F2C /* SearchScope+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D097F41A25BE3E1A00859F2C /* SearchScope+Extensions.swift */; };
|
||||||
|
D097F4C125BFA04C00859F2C /* NotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */; };
|
||||||
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */; };
|
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */; };
|
||||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */; };
|
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */; };
|
||||||
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
|
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
|
||||||
|
@ -270,6 +271,7 @@
|
||||||
D08E52D1257C811200FA2C5F /* ShareExtensionError+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ShareExtensionError+Extensions.swift"; sourceTree = "<group>"; };
|
D08E52D1257C811200FA2C5F /* ShareExtensionError+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ShareExtensionError+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
D08E52ED257D757100FA2C5F /* CompositionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionView.swift; sourceTree = "<group>"; };
|
D08E52ED257D757100FA2C5F /* CompositionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionView.swift; sourceTree = "<group>"; };
|
||||||
D097F41A25BE3E1A00859F2C /* SearchScope+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchScope+Extensions.swift"; sourceTree = "<group>"; };
|
D097F41A25BE3E1A00859F2C /* SearchScope+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchScope+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsViewController.swift; sourceTree = "<group>"; };
|
||||||
D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDataSource.swift; sourceTree = "<group>"; };
|
D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDataSource.swift; sourceTree = "<group>"; };
|
||||||
D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusView.swift; sourceTree = "<group>"; };
|
D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusView.swift; sourceTree = "<group>"; };
|
||||||
D0AD03552505814D0085A466 /* Base16 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base16; sourceTree = "<group>"; };
|
D0AD03552505814D0085A466 /* Base16 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base16; sourceTree = "<group>"; };
|
||||||
|
@ -570,6 +572,7 @@
|
||||||
D08B8D3C253F929E00B1EBEF /* ImageViewController.swift */,
|
D08B8D3C253F929E00B1EBEF /* ImageViewController.swift */,
|
||||||
D035F86825B7F2ED00DC75ED /* MainNavigationViewController.swift */,
|
D035F86825B7F2ED00DC75ED /* MainNavigationViewController.swift */,
|
||||||
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */,
|
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */,
|
||||||
|
D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */,
|
||||||
D06BC5E525202AD90079541D /* ProfileViewController.swift */,
|
D06BC5E525202AD90079541D /* ProfileViewController.swift */,
|
||||||
D0F0B12D251A97E400942152 /* TableViewController.swift */,
|
D0F0B12D251A97E400942152 /* TableViewController.swift */,
|
||||||
D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */,
|
D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */,
|
||||||
|
@ -940,6 +943,7 @@
|
||||||
D0D2AC6725BD0484003D5DF2 /* LineChartView.swift in Sources */,
|
D0D2AC6725BD0484003D5DF2 /* LineChartView.swift in Sources */,
|
||||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */,
|
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */,
|
||||||
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
||||||
|
D097F4C125BFA04C00859F2C /* NotificationsViewController.swift in Sources */,
|
||||||
D0E1F583251F13EC00D45315 /* WebfingerIndicatorView.swift in Sources */,
|
D0E1F583251F13EC00D45315 /* WebfingerIndicatorView.swift in Sources */,
|
||||||
D0BEB20524FA1107001B0F04 /* FiltersView.swift in Sources */,
|
D0BEB20524FA1107001B0F04 /* FiltersView.swift in Sources */,
|
||||||
D035F88725B8016000DC75ED /* NavigationViewModel+Extensions.swift in Sources */,
|
D035F88725B8016000DC75ED /* NavigationViewModel+Extensions.swift in Sources */,
|
||||||
|
|
|
@ -253,8 +253,10 @@ public extension IdentityService {
|
||||||
ExploreService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
|
ExploreService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
|
||||||
}
|
}
|
||||||
|
|
||||||
func notificationsService() -> NotificationsService {
|
func notificationsService(excludeTypes: Set<MastodonNotification.NotificationType>) -> NotificationsService {
|
||||||
NotificationsService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
|
NotificationsService(excludeTypes: excludeTypes,
|
||||||
|
mastodonAPIClient: mastodonAPIClient,
|
||||||
|
contentDatabase: contentDatabase)
|
||||||
}
|
}
|
||||||
|
|
||||||
func conversationsService() -> ConversationsService {
|
func conversationsService() -> ConversationsService {
|
||||||
|
|
|
@ -11,18 +11,22 @@ public struct NotificationsService {
|
||||||
public let nextPageMaxId: AnyPublisher<String, Never>
|
public let nextPageMaxId: AnyPublisher<String, Never>
|
||||||
public let navigationService: NavigationService
|
public let navigationService: NavigationService
|
||||||
|
|
||||||
|
private let excludeTypes: Set<MastodonNotification.NotificationType>
|
||||||
private let mastodonAPIClient: MastodonAPIClient
|
private let mastodonAPIClient: MastodonAPIClient
|
||||||
private let contentDatabase: ContentDatabase
|
private let contentDatabase: ContentDatabase
|
||||||
private let nextPageMaxIdSubject: CurrentValueSubject<String, Never>
|
private let nextPageMaxIdSubject: CurrentValueSubject<String, Never>
|
||||||
|
|
||||||
init(mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
|
init(excludeTypes: Set<MastodonNotification.NotificationType>,
|
||||||
|
mastodonAPIClient: MastodonAPIClient,
|
||||||
|
contentDatabase: ContentDatabase) {
|
||||||
|
self.excludeTypes = excludeTypes
|
||||||
self.mastodonAPIClient = mastodonAPIClient
|
self.mastodonAPIClient = mastodonAPIClient
|
||||||
self.contentDatabase = contentDatabase
|
self.contentDatabase = contentDatabase
|
||||||
|
|
||||||
let nextPageMaxIdSubject = CurrentValueSubject<String, Never>(String(Int.max))
|
let nextPageMaxIdSubject = CurrentValueSubject<String, Never>(String(Int.max))
|
||||||
|
|
||||||
self.nextPageMaxIdSubject = nextPageMaxIdSubject
|
self.nextPageMaxIdSubject = nextPageMaxIdSubject
|
||||||
sections = contentDatabase.notificationsPublisher()
|
sections = contentDatabase.notificationsPublisher(excludeTypes: excludeTypes)
|
||||||
.handleEvents(receiveOutput: {
|
.handleEvents(receiveOutput: {
|
||||||
guard case let .notification(notification, _) = $0.last?.items.last,
|
guard case let .notification(notification, _) = $0.last?.items.last,
|
||||||
notification.id < nextPageMaxIdSubject.value
|
notification.id < nextPageMaxIdSubject.value
|
||||||
|
@ -37,10 +41,12 @@ public struct NotificationsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NotificationsService: CollectionService {
|
extension NotificationsService: CollectionService {
|
||||||
public var markerTimeline: Marker.Timeline? { .notifications }
|
public var markerTimeline: Marker.Timeline? { excludeTypes.isEmpty ? .notifications : nil }
|
||||||
|
|
||||||
public func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error> {
|
public func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error> {
|
||||||
mastodonAPIClient.pagedRequest(NotificationsEndpoint.notifications, maxId: maxId, minId: minId)
|
mastodonAPIClient.pagedRequest(NotificationsEndpoint.notifications(excludeTypes: excludeTypes),
|
||||||
|
maxId: maxId,
|
||||||
|
minId: minId)
|
||||||
.handleEvents(receiveOutput: {
|
.handleEvents(receiveOutput: {
|
||||||
guard let maxId = $0.info.maxId, maxId < nextPageMaxIdSubject.value else { return }
|
guard let maxId = $0.info.maxId, maxId < nextPageMaxIdSubject.value else { return }
|
||||||
|
|
||||||
|
|
|
@ -63,14 +63,8 @@ private extension MainNavigationViewController {
|
||||||
rootViewModel: rootViewModel)
|
rootViewModel: rootViewModel)
|
||||||
]
|
]
|
||||||
|
|
||||||
if let notificationsViewModel = viewModel.notificationsViewModel {
|
if viewModel.identityContext.identity.authenticated {
|
||||||
let notificationsViewController = TableViewController(
|
controllers.append(NotificationsViewController(viewModel: viewModel, rootViewModel: rootViewModel))
|
||||||
viewModel: notificationsViewModel,
|
|
||||||
rootViewModel: rootViewModel)
|
|
||||||
|
|
||||||
notificationsViewController.tabBarItem = NavigationViewModel.Tab.notifications.tabBarItem
|
|
||||||
|
|
||||||
controllers.append(notificationsViewController)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let conversationsViewModel = viewModel.conversationsViewModel {
|
if let conversationsViewModel = viewModel.conversationsViewModel {
|
||||||
|
|
109
View Controllers/NotificationsViewController.swift
Normal file
109
View Controllers/NotificationsViewController.swift
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright © 2021 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Mastodon
|
||||||
|
import UIKit
|
||||||
|
import ViewModels
|
||||||
|
|
||||||
|
final class NotificationsViewController: UIPageViewController {
|
||||||
|
private let segmentedControl = UISegmentedControl(items: [
|
||||||
|
NSLocalizedString("notifications.all", comment: ""),
|
||||||
|
NSLocalizedString("notifications.mentions", comment: "")
|
||||||
|
])
|
||||||
|
private let notificationViewControllers: [TableViewController]
|
||||||
|
private let viewModel: NavigationViewModel
|
||||||
|
private let rootViewModel: RootViewModel
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
init(viewModel: NavigationViewModel, rootViewModel: RootViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
self.rootViewModel = rootViewModel
|
||||||
|
|
||||||
|
var excludingAllExceptMentions = Set(MastodonNotification.NotificationType.allCasesExceptUnknown)
|
||||||
|
|
||||||
|
excludingAllExceptMentions.remove(.mention)
|
||||||
|
|
||||||
|
notificationViewControllers = [
|
||||||
|
TableViewController(viewModel: viewModel.notificationsViewModel(excludeTypes: []),
|
||||||
|
rootViewModel: rootViewModel),
|
||||||
|
TableViewController(viewModel: viewModel.notificationsViewModel(excludeTypes: excludingAllExceptMentions),
|
||||||
|
rootViewModel: rootViewModel)
|
||||||
|
]
|
||||||
|
|
||||||
|
super.init(transitionStyle: .scroll,
|
||||||
|
navigationOrientation: .horizontal,
|
||||||
|
options: [.interPageSpacing: CGFloat.defaultSpacing])
|
||||||
|
|
||||||
|
if let firstViewController = notificationViewControllers.first {
|
||||||
|
setViewControllers([firstViewController], direction: .forward, animated: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
tabBarItem = NavigationViewModel.Tab.notifications.tabBarItem
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
dataSource = self
|
||||||
|
delegate = self
|
||||||
|
|
||||||
|
navigationItem.titleView = segmentedControl
|
||||||
|
segmentedControl.selectedSegmentIndex = 0
|
||||||
|
segmentedControl.addAction(
|
||||||
|
UIAction { [weak self] _ in
|
||||||
|
guard let self = self,
|
||||||
|
let currentViewController = self.viewControllers?.first as? TableViewController,
|
||||||
|
let currentIndex = self.notificationViewControllers.firstIndex(of: currentViewController),
|
||||||
|
self.segmentedControl.selectedSegmentIndex != currentIndex
|
||||||
|
else { return }
|
||||||
|
|
||||||
|
self.setViewControllers(
|
||||||
|
[self.notificationViewControllers[self.segmentedControl.selectedSegmentIndex]],
|
||||||
|
direction: self.segmentedControl.selectedSegmentIndex > currentIndex ? .forward : .reverse,
|
||||||
|
animated: !UIAccessibility.isReduceMotionEnabled)
|
||||||
|
},
|
||||||
|
for: .valueChanged)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NotificationsViewController: UIPageViewControllerDataSource {
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController,
|
||||||
|
viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||||
|
guard
|
||||||
|
let viewController = viewController as? TableViewController,
|
||||||
|
let index = notificationViewControllers.firstIndex(of: viewController),
|
||||||
|
index + 1 < notificationViewControllers.count
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
|
return notificationViewControllers[index + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController,
|
||||||
|
viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||||
|
guard
|
||||||
|
let viewController = viewController as? TableViewController,
|
||||||
|
let index = notificationViewControllers.firstIndex(of: viewController),
|
||||||
|
index > 0
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
|
return notificationViewControllers[index - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NotificationsViewController: UIPageViewControllerDelegate {
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController,
|
||||||
|
didFinishAnimating finished: Bool,
|
||||||
|
previousViewControllers: [UIViewController],
|
||||||
|
transitionCompleted completed: Bool) {
|
||||||
|
guard let viewController = viewControllers?.first as? TableViewController,
|
||||||
|
let index = notificationViewControllers.firstIndex(of: viewController)
|
||||||
|
else { return }
|
||||||
|
|
||||||
|
segmentedControl.selectedSegmentIndex = index
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,20 +23,6 @@ public final class NavigationViewModel: ObservableObject {
|
||||||
return exploreViewModel
|
return exploreViewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public lazy var notificationsViewModel: CollectionViewModel? = {
|
|
||||||
if identityContext.identity.authenticated {
|
|
||||||
let notificationsViewModel = CollectionItemsViewModel(
|
|
||||||
collectionService: identityContext.service.notificationsService(),
|
|
||||||
identityContext: identityContext)
|
|
||||||
|
|
||||||
notificationsViewModel.request(maxId: nil, minId: nil, search: nil)
|
|
||||||
|
|
||||||
return notificationsViewModel
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
public lazy var conversationsViewModel: CollectionViewModel? = {
|
public lazy var conversationsViewModel: CollectionViewModel? = {
|
||||||
if identityContext.identity.authenticated {
|
if identityContext.identity.authenticated {
|
||||||
let conversationsViewModel = CollectionItemsViewModel(
|
let conversationsViewModel = CollectionItemsViewModel(
|
||||||
|
@ -140,4 +126,14 @@ public extension NavigationViewModel {
|
||||||
collectionService: identityContext.service.service(timeline: timeline),
|
collectionService: identityContext.service.service(timeline: timeline),
|
||||||
identityContext: identityContext)
|
identityContext: identityContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func notificationsViewModel(excludeTypes: Set<MastodonNotification.NotificationType>) -> CollectionItemsViewModel {
|
||||||
|
let viewModel = CollectionItemsViewModel(
|
||||||
|
collectionService: identityContext.service.notificationsService(excludeTypes: excludeTypes),
|
||||||
|
identityContext: identityContext)
|
||||||
|
|
||||||
|
viewModel.request(maxId: nil, minId: nil, search: nil)
|
||||||
|
|
||||||
|
return viewModel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,8 @@ extension MastodonNotification.NotificationType {
|
||||||
return "star.fill"
|
return "star.fill"
|
||||||
case .poll:
|
case .poll:
|
||||||
return "chart.bar.doc.horizontal"
|
return "chart.bar.doc.horizontal"
|
||||||
|
case .status:
|
||||||
|
return "house"
|
||||||
case .mention, .unknown:
|
case .mention, .unknown:
|
||||||
return "at"
|
return "at"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue