Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mod Mail Feed Loader #1692

Merged
merged 7 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions Mlem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@
CD332D7C2CA71E6F00A53988 /* GifView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD332D7B2CA71E6E00A53988 /* GifView.swift */; };
CD332D7E2CA7486000A53988 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD332D7D2CA7485D00A53988 /* String+Extensions.swift */; };
CD33CA522D3C18BF00106C8C /* ImageViewer+Views.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD33CA512D3C18AE00106C8C /* ImageViewer+Views.swift */; };
CD383BBD2D41B91E00F9F247 /* MlemMiddleware in Frameworks */ = {isa = PBXBuildFile; productRef = CD383BBC2D41B91E00F9F247 /* MlemMiddleware */; };
CD3FC6802D4A75090088E63B /* CounterApperance+StaticValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3FC67F2D4A75050088E63B /* CounterApperance+StaticValues.swift */; };
CD4368C12AE23FD400BD8BD1 /* Semaphore in Frameworks */ = {isa = PBXBuildFile; productRef = CD4368C02AE23FD400BD8BD1 /* Semaphore */; };
CD43E8B32BF2C24E007C3D71 /* ContentLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD43E8B22BF2C24E007C3D71 /* ContentLoader.swift */; };
Expand Down Expand Up @@ -485,6 +484,7 @@
CDE4AC472CA372B600981010 /* SDWebImageWebPCoder in Frameworks */ = {isa = PBXBuildFile; productRef = CDE4AC462CA372B600981010 /* SDWebImageWebPCoder */; };
CDEE15522D22190600EB9D7B /* ErrorsTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDEE15512D22190000EB9D7B /* ErrorsTracker.swift */; };
CDEE15542D22364B00EB9D7B /* ErrorLogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDEE15532D22364500EB9D7B /* ErrorLogView.swift */; };
CDF5B7092D4ED47000412DBD /* MlemMiddleware in Frameworks */ = {isa = PBXBuildFile; productRef = CDF5B7082D4ED47000412DBD /* MlemMiddleware */; };
CDF9EF332AB2845C003F885B /* Icons.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF9EF322AB2845C003F885B /* Icons.swift */; };
CDFB8C692C7796020070845F /* View+DynamicBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFB8C682C7796020070845F /* View+DynamicBlur.swift */; };
CDFF11712D3D93DC00386B71 /* ConditionalIconLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFF11702D3D93D900386B71 /* ConditionalIconLabelStyle.swift */; };
Expand Down Expand Up @@ -999,7 +999,7 @@
636250DC2A18111400FC59B4 /* KeychainAccess in Frameworks */,
CDE4AC452CA370E000981010 /* SDWebImageSwiftUI in Frameworks */,
CD4368C12AE23FD400BD8BD1 /* Semaphore in Frameworks */,
CD383BBD2D41B91E00F9F247 /* MlemMiddleware in Frameworks */,
CDF5B7092D4ED47000412DBD /* MlemMiddleware in Frameworks */,
B104A6DE2A59BF3C00B3E725 /* NukeVideo in Frameworks */,
CDE4AC472CA372B600981010 /* SDWebImageWebPCoder in Frameworks */,
B104A6DC2A59BF3C00B3E725 /* NukeUI in Frameworks */,
Expand Down Expand Up @@ -2213,7 +2213,7 @@
CDE4AC442CA370E000981010 /* SDWebImageSwiftUI */,
CDE4AC462CA372B600981010 /* SDWebImageWebPCoder */,
CD64A9192CA37E8D007CA7E6 /* Gifu */,
CD383BBC2D41B91E00F9F247 /* MlemMiddleware */,
CDF5B7082D4ED47000412DBD /* MlemMiddleware */,
);
productName = Mlem;
productReference = 6363D5C127EE196700E34822 /* Mlem.app */;
Expand Down Expand Up @@ -2301,7 +2301,7 @@
CDE4AC402CA3706400981010 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */,
CDE4AC412CA3706F00981010 /* XCRemoteSwiftPackageReference "SDWebImageWebPCoder" */,
CD64A9182CA37D63007CA7E6 /* XCRemoteSwiftPackageReference "Gifu" */,
CD5CAA0D2D41B8FF008E20F2 /* XCRemoteSwiftPackageReference "MlemMiddleware" */,
CDDEDC332D4ED44000845271 /* XCRemoteSwiftPackageReference "MlemMiddleware" */,
);
productRefGroup = 6363D5C227EE196700E34822 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -3260,14 +3260,6 @@
minimumVersion = 0.0.8;
};
};
CD5CAA0D2D41B8FF008E20F2 /* XCRemoteSwiftPackageReference "MlemMiddleware" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mlemgroup/MlemMiddleware";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.71.0;
};
};
CD64A9182CA37D63007CA7E6 /* XCRemoteSwiftPackageReference "Gifu" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kaishin/Gifu";
Expand All @@ -3276,6 +3268,14 @@
kind = branch;
};
};
CDDEDC332D4ED44000845271 /* XCRemoteSwiftPackageReference "MlemMiddleware" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mlemgroup/MlemMiddleware";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.72.0;
};
};
CDE4AC402CA3706400981010 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SDWebImage/SDWebImageSwiftUI";
Expand Down Expand Up @@ -3340,11 +3340,6 @@
package = B104A6D62A59BF3C00B3E725 /* XCRemoteSwiftPackageReference "Nuke" */;
productName = NukeVideo;
};
CD383BBC2D41B91E00F9F247 /* MlemMiddleware */ = {
isa = XCSwiftPackageProductDependency;
package = CD5CAA0D2D41B8FF008E20F2 /* XCRemoteSwiftPackageReference "MlemMiddleware" */;
productName = MlemMiddleware;
};
CD4368C02AE23FD400BD8BD1 /* Semaphore */ = {
isa = XCSwiftPackageProductDependency;
package = CD4368BF2AE23FD400BD8BD1 /* XCRemoteSwiftPackageReference "Semaphore" */;
Expand All @@ -3365,6 +3360,11 @@
package = CDE4AC412CA3706F00981010 /* XCRemoteSwiftPackageReference "SDWebImageWebPCoder" */;
productName = SDWebImageWebPCoder;
};
CDF5B7082D4ED47000412DBD /* MlemMiddleware */ = {
isa = XCSwiftPackageProductDependency;
package = CDDEDC332D4ED44000845271 /* XCRemoteSwiftPackageReference "MlemMiddleware" */;
productName = MlemMiddleware;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 6363D5B927EE196700E34822 /* Project object */;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/mlemgroup/MlemMiddleware",
"state" : {
"revision" : "ecb1d6011920be580055b539774d23513bb9b902",
"version" : "0.71.0"
"revision" : "80ef290b94ae5bf3b1e83e62d333f45432e2dfe0",
"version" : "0.72.0"
}
},
{
Expand Down
71 changes: 13 additions & 58 deletions Mlem/App/Views/Root/Tabs/Inbox/InboxView+Views.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension InboxView {
var inboxFeedView: some View {
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
Section {
ForEach(feedLoader.items, id: \.actorId) { item in
ForEach(feedLoader.items, id: \.inboxId) { item in
Group {
switch item {
case let .message(message):
Expand Down Expand Up @@ -58,33 +58,23 @@ extension InboxView {
}
)
}
switch selectedModTab {
case .reports:
ForEach(currentModFeedLoader.items, id: \.inboxId) { item in
Group {
if let reports {
ForEach(reports, id: \.cacheId) { report in
ReportView(report: report)
.padding([.horizontal, .bottom], Constants.main.standardSpacing)
}
} else {
ProgressView()
.padding(.top)
switch item {
case let .application(application):
RegistrationApplicationView(application: application)
case let .report(report):
ReportView(report: report)
}
}
.onAppear(perform: loadReports)
case .applications:
Group {
if let applications {
ForEach(applications, id: \.cacheId) { application in
RegistrationApplicationView(application: application)
.padding([.horizontal, .bottom], Constants.main.standardSpacing)
}
} else {
ProgressView()
.padding(.top)
.padding([.horizontal, .bottom], Constants.main.standardSpacing)
.onAppear {
do {
try currentModFeedLoader.loadIfThreshold(item)
} catch {
handleError(error)
}
}
.onAppear(perform: loadApplications)
}
}
.padding(.top, Constants.main.standardSpacing)
Expand Down Expand Up @@ -242,41 +232,6 @@ extension InboxView {
}
}

func loadReports() {
if reports == nil {
Task { @MainActor in
do {
async let postReports = await appState.firstApi.getPostReports()
async let commentReports = await appState.firstApi.getCommentReports()
async let messageReports: [Report] = await {
if await appState.firstApi.isAdmin {
return try await appState.firstApi.getMessageReports()
} else {
return []
}
}()

let combined = try await (postReports + commentReports + messageReports)
self.reports = combined.sorted { $0.created > $1.created }
} catch {
handleError(error)
}
}
}
}

func loadApplications() {
if applications == nil {
Task { @MainActor in
do {
self.applications = try await appState.firstApi.getRegistrationApplications()
} catch {
handleError(error)
}
}
}
}

var showBadge: Bool {
guard let unreadCount = (appState.firstSession as? UserSession)?.unreadCount else { return false }
switch selectedFeed {
Expand Down
53 changes: 30 additions & 23 deletions Mlem/App/Views/Root/Tabs/Inbox/InboxView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ struct InboxView: View {
@State var messageFeedLoader: MessageChildFeedLoader
@State var inboxFeedLoader: InboxFeedLoader

@State var reportFeedLoader: ReportChildFeedLoader
@State var applicationFeedLoader: ApplicationChildFeedLoader
@State var modMailFeedLoader: ModMailFeedLoader

@State var showRefreshPopup: Bool = false
@State var waitingOnMarkAllAsRead: Bool = false
@State var markAllAsReadTrigger: Bool = false
Expand All @@ -38,37 +42,28 @@ struct InboxView: View {
@Setting(\.internetSpeed) var internetSpeed
@Setting(\.showReadInInbox) var showRead

let replyFeedLoader: ReplyChildFeedLoader = .init(
api: AppState.main.firstApi,
pageSize: internetSpeed.pageSize,
sortType: .new,
showRead: showRead
)
let mentionFeedLoader: MentionChildFeedLoader = .init(
api: AppState.main.firstApi,
pageSize: internetSpeed.pageSize,
sortType: .new,
showRead: showRead
)
let messageFeedLoader: MessageChildFeedLoader = .init(
api: AppState.main.firstApi,
pageSize: internetSpeed.pageSize,
sortType: .new,
showRead: showRead
let inboxFeedLoaders = InboxFeedLoader.setup(
api: AppState.main.firstApi,
pageSize: internetSpeed.pageSize,
sortType: .new,
showRead: showRead
)

let inboxFeedLoader: InboxFeedLoader = .init(
self._replyFeedLoader = .init(wrappedValue: inboxFeedLoaders.replyFeedLoader)
self._mentionFeedLoader = .init(wrappedValue: inboxFeedLoaders.mentionFeedLoader)
self._messageFeedLoader = .init(wrappedValue: inboxFeedLoaders.messageFeedLoader)
self._inboxFeedLoader = .init(wrappedValue: inboxFeedLoaders.inboxFeedLoader)

let modMailFeedLoaders = ModMailFeedLoader.setup(
api: AppState.main.firstApi,
pageSize: internetSpeed.pageSize,
sources: [replyFeedLoader, mentionFeedLoader, messageFeedLoader],
sortType: .new,
showRead: showRead
)

self._replyFeedLoader = .init(wrappedValue: replyFeedLoader)
self._mentionFeedLoader = .init(wrappedValue: mentionFeedLoader)
self._messageFeedLoader = .init(wrappedValue: messageFeedLoader)
self._inboxFeedLoader = .init(wrappedValue: inboxFeedLoader)
self._reportFeedLoader = .init(wrappedValue: modMailFeedLoaders.reportFeedLoader)
self._applicationFeedLoader = .init(wrappedValue: modMailFeedLoaders.applicationFeedLoader)
self._modMailFeedLoader = .init(wrappedValue: modMailFeedLoaders.modMailFeedLoader)
}

var feedLoader: StandardFeedLoader<InboxItem> {
Expand All @@ -84,6 +79,13 @@ struct InboxView: View {
}
}

var currentModFeedLoader: StandardFeedLoader<ModMailItem> {
switch selectedModTab {
case .applications: applicationFeedLoader
case .reports: reportFeedLoader
}
}

var availableFeeds: [Feed] {
if appState.firstApi.isAdmin || !(appState.firstPerson?.moderatedCommunities.isEmpty ?? true) {
return [.inbox, .modMail]
Expand All @@ -100,10 +102,12 @@ struct InboxView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbar { toolbar }
.loadFeed(inboxFeedLoader)
.loadFeed(modMailFeedLoader)
.onChange(of: appState.firstApi, initial: false) {
if appState.firstAccount is UserAccount {
Task {
await inboxFeedLoader.changeApi(to: appState.firstApi, context: filtersTracker.filterContext)
await modMailFeedLoader.changeApi(to: appState.firstApi, context: filtersTracker.filterContext)
}
showRefreshPopup = true
}
Expand All @@ -113,8 +117,10 @@ struct InboxView: View {
do {
if showRead {
try await inboxFeedLoader.showRead()
try await modMailFeedLoader.showRead()
} else {
try await inboxFeedLoader.hideRead()
try await modMailFeedLoader.hideRead()
}
} catch {
handleError(error)
Expand Down Expand Up @@ -174,6 +180,7 @@ struct InboxView: View {
private func refresh() async {
do {
try await inboxFeedLoader.refresh(clearBeforeRefresh: true)
try await modMailFeedLoader.refresh(clearBeforeRefresh: true)
} catch {
handleError(error)
}
Expand Down