Skip to content

Commit

Permalink
Purge Posts & Comments (#1420)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sjmarf authored Nov 1, 2024
1 parent ca6a9e5 commit afddd61
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 17 deletions.
18 changes: 15 additions & 3 deletions Mlem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
032C32162C36F65500595286 /* ReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C32152C36F65500595286 /* ReplyView.swift */; };
032C32182C36F70300595286 /* ReplyBarConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C32172C36F70300595286 /* ReplyBarConfiguration.swift */; };
032C321A2C36F75800595286 /* Reply1Providing+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C32192C36F75800595286 /* Reply1Providing+Extensions.swift */; };
0331715E2CCD6D95002DA370 /* ContentPurgeEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0331715D2CCD6D95002DA370 /* ContentPurgeEditorView.swift */; };
033171782CCE89E3002DA370 /* PurgableProviding+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033171772CCE89E3002DA370 /* PurgableProviding+Extensions.swift */; };
033EF4102CB9AEF7004D8A3F /* ExpandedPostView+Views.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033EF40F2CB9AEF7004D8A3F /* ExpandedPostView+Views.swift */; };
033F84AD2C298466002E3EDF /* SectionIndexTitles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033F84AC2C298466002E3EDF /* SectionIndexTitles.swift */; };
033F84B12C29907F002E3EDF /* FeedbackType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033F84B02C29907F002E3EDF /* FeedbackType.swift */; };
Expand Down Expand Up @@ -201,12 +203,12 @@
03AFD0E52C3C14D50054B8AD /* InstanceStubProviding+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AFD0E42C3C14D50054B8AD /* InstanceStubProviding+Extensions.swift */; };
03B04FC02C5FC32300824128 /* SimpleAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B04FBF2C5FC32300824128 /* SimpleAvatarView.swift */; };
03B0EB6F2C87827A00F79FDF /* ExpandedPostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B0EB6E2C87827A00F79FDF /* ExpandedPostView.swift */; };
03B25B3B2CC44FFF00EB6DF5 /* UploadConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B3A2CC44FFF00EB6DF5 /* UploadConfirmationView.swift */; };
03B25B2F2CC43F8600EB6DF5 /* InstanceSafetyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B2E2CC43F8600EB6DF5 /* InstanceSafetyView.swift */; };
03B25B312CC4403500EB6DF5 /* Fediseer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B302CC4403500EB6DF5 /* Fediseer.swift */; };
03B25B332CC440A600EB6DF5 /* FediseerOpinionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B322CC440A600EB6DF5 /* FediseerOpinionView.swift */; };
03B25B352CC4446400EB6DF5 /* FediseerOpinionListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B342CC4446400EB6DF5 /* FediseerOpinionListView.swift */; };
03B25B372CC4478600EB6DF5 /* FediseerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B362CC4478600EB6DF5 /* FediseerInfoView.swift */; };
03B25B3B2CC44FFF00EB6DF5 /* UploadConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B25B3A2CC44FFF00EB6DF5 /* UploadConfirmationView.swift */; };
03B431B22C44409D001A1EB5 /* CommentEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B431B12C44409D001A1EB5 /* CommentEditorView.swift */; };
03B431B42C4481C3001A1EB5 /* MarkdownTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B431B32C4481C3001A1EB5 /* MarkdownTextEditor.swift */; };
03B431B62C454D49001A1EB5 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B431B52C454D49001A1EB5 /* UIImage+Extensions.swift */; };
Expand All @@ -224,6 +226,7 @@
03CBD1932C61369A00E870BC /* Interactable2Providing+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CBD1922C61369A00E870BC /* Interactable2Providing+Extensions.swift */; };
03CCDAA02BF2795300C0C851 /* LoginPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CCDA9F2BF2795300C0C851 /* LoginPage.swift */; };
03CCDAA42BF2852E00C0C851 /* LoginTotpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CCDAA32BF2852E00C0C851 /* LoginTotpView.swift */; };
03D0273C2CD3BA5100984519 /* PersonContent+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D0273B2CD3BA5100984519 /* PersonContent+Extensions.swift */; };
03D2A6372C00F92400ED4FF2 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D2A6362C00F92400ED4FF2 /* Session.swift */; };
03D2A6392C00FAE000ED4FF2 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D2A6382C00FAE000ED4FF2 /* UserAccount.swift */; };
03D2A63B2C010B7500ED4FF2 /* GuestAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D2A63A2C010B7500ED4FF2 /* GuestAccount.swift */; };
Expand Down Expand Up @@ -466,6 +469,8 @@
032C32152C36F65500595286 /* ReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyView.swift; sourceTree = "<group>"; };
032C32172C36F70300595286 /* ReplyBarConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyBarConfiguration.swift; sourceTree = "<group>"; };
032C32192C36F75800595286 /* Reply1Providing+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Reply1Providing+Extensions.swift"; sourceTree = "<group>"; };
0331715D2CCD6D95002DA370 /* ContentPurgeEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentPurgeEditorView.swift; sourceTree = "<group>"; };
033171772CCE89E3002DA370 /* PurgableProviding+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PurgableProviding+Extensions.swift"; sourceTree = "<group>"; };
033EF40F2CB9AEF7004D8A3F /* ExpandedPostView+Views.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ExpandedPostView+Views.swift"; sourceTree = "<group>"; };
033F84AC2C298466002E3EDF /* SectionIndexTitles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionIndexTitles.swift; sourceTree = "<group>"; };
033F84B02C29907F002E3EDF /* FeedbackType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -606,12 +611,12 @@
03AFD0E42C3C14D50054B8AD /* InstanceStubProviding+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstanceStubProviding+Extensions.swift"; sourceTree = "<group>"; };
03B04FBF2C5FC32300824128 /* SimpleAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleAvatarView.swift; sourceTree = "<group>"; };
03B0EB6E2C87827A00F79FDF /* ExpandedPostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandedPostView.swift; sourceTree = "<group>"; };
03B25B3A2CC44FFF00EB6DF5 /* UploadConfirmationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadConfirmationView.swift; sourceTree = "<group>"; };
03B25B2E2CC43F8600EB6DF5 /* InstanceSafetyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceSafetyView.swift; sourceTree = "<group>"; };
03B25B302CC4403500EB6DF5 /* Fediseer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fediseer.swift; sourceTree = "<group>"; };
03B25B322CC440A600EB6DF5 /* FediseerOpinionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FediseerOpinionView.swift; sourceTree = "<group>"; };
03B25B342CC4446400EB6DF5 /* FediseerOpinionListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FediseerOpinionListView.swift; sourceTree = "<group>"; };
03B25B362CC4478600EB6DF5 /* FediseerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FediseerInfoView.swift; sourceTree = "<group>"; };
03B25B3A2CC44FFF00EB6DF5 /* UploadConfirmationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadConfirmationView.swift; sourceTree = "<group>"; };
03B431B12C44409D001A1EB5 /* CommentEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentEditorView.swift; sourceTree = "<group>"; };
03B431B32C4481C3001A1EB5 /* MarkdownTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownTextEditor.swift; sourceTree = "<group>"; };
03B431B52C454D49001A1EB5 /* UIImage+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extensions.swift"; sourceTree = "<group>"; };
Expand All @@ -629,6 +634,7 @@
03CBD1922C61369A00E870BC /* Interactable2Providing+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Interactable2Providing+Extensions.swift"; sourceTree = "<group>"; };
03CCDA9F2BF2795300C0C851 /* LoginPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginPage.swift; sourceTree = "<group>"; };
03CCDAA32BF2852E00C0C851 /* LoginTotpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginTotpView.swift; sourceTree = "<group>"; };
03D0273B2CD3BA5100984519 /* PersonContent+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PersonContent+Extensions.swift"; sourceTree = "<group>"; };
03D2A6362C00F92400ED4FF2 /* Session.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Session.swift; sourceTree = "<group>"; };
03D2A6382C00FAE000ED4FF2 /* UserAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAccount.swift; sourceTree = "<group>"; };
03D2A63A2C010B7500ED4FF2 /* GuestAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuestAccount.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1076,6 +1082,7 @@
0397D4902C6CE871002C6CDC /* PostEditor */,
0397D4792C693444002C6CDC /* ReportEditorView.swift */,
038028FC2CB72A2A0091A8A2 /* ContentRemovalEditorView.swift */,
0331715D2CCD6D95002DA370 /* ContentPurgeEditorView.swift */,
CDD99C3B2C73F3FF0010367F /* DeleteAccountView.swift */,
03B25B3A2CC44FFF00EB6DF5 /* UploadConfirmationView.swift */,
);
Expand Down Expand Up @@ -1714,7 +1721,9 @@
0389DDC22C38907C0005B808 /* Message1Providing+Extensions.swift */,
032C320B2C3482CA00595286 /* Person1Providing+Extensions.swift */,
03E614E32C0BCC7B00F692A4 /* Post1Providing+Extensions.swift */,
03D0273B2CD3BA5100984519 /* PersonContent+Extensions.swift */,
039D75632C4EEE69004F24C2 /* DeletableProviding+Extensions.swift */,
033171772CCE89E3002DA370 /* PurgableProviding+Extensions.swift */,
032C32192C36F75800595286 /* Reply1Providing+Extensions.swift */,
032C32072C34469900595286 /* SelectableContentProviding+Extensions.swift */,
0389DDC62C389F840005B808 /* UnreadCount+Extensions.swift */,
Expand Down Expand Up @@ -2117,6 +2126,7 @@
CDAA02DD2C81792500D75633 /* SolarizedPalette.swift in Sources */,
035EDF032C2ED0DE00F51144 /* PersonListRowBody.swift in Sources */,
03FD6CB02C9B719100500FD6 /* View+PopupAnchor.swift in Sources */,
0331715E2CCD6D95002DA370 /* ContentPurgeEditorView.swift in Sources */,
CDBFCB652C03920C008CD468 /* PostLinkHostView.swift in Sources */,
03B04FC02C5FC32300824128 /* SimpleAvatarView.swift in Sources */,
035BE08D2BDE88EC00F77D73 /* NavigationLayerView.swift in Sources */,
Expand Down Expand Up @@ -2186,6 +2196,7 @@
CD9D243D2CC1DF59006E5F3F /* AccountType.swift in Sources */,
0320B6632C8F8D5A00D38548 /* InstanceSort.swift in Sources */,
0397D4912C6CE871002C6CDC /* PostEditorView.swift in Sources */,
033171782CCE89E3002DA370 /* PurgableProviding+Extensions.swift in Sources */,
03D2A63B2C010B7500ED4FF2 /* GuestAccount.swift in Sources */,
CDE1F1962C63DF89008AF042 /* PhoneConstants.swift in Sources */,
0397D4862C6A24D2002C6CDC /* ReportableProviding+Extensions.swift in Sources */,
Expand Down Expand Up @@ -2414,6 +2425,7 @@
CD4D58AD2B86BE7100B82964 /* QuickSwitcherView.swift in Sources */,
0397D4642C676CA8002C6CDC /* FeedSortPicker.swift in Sources */,
0355F9462C150B2300605248 /* ExternalApiInfoView.swift in Sources */,
03D0273C2CD3BA5100984519 /* PersonContent+Extensions.swift in Sources */,
CD13CC612C5D262E001AF428 /* MediaLoadingState.swift in Sources */,
03CBD1932C61369A00E870BC /* Interactable2Providing+Extensions.swift in Sources */,
03B25B3B2CC44FFF00EB6DF5 /* UploadConfirmationView.swift in Sources */,
Expand Down Expand Up @@ -2872,7 +2884,7 @@
repositoryURL = "https://github.com/mlemgroup/MlemMiddleware";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.45.0;
minimumVersion = 0.46.0;
};
};
CDE4AC402CA3706400981010 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/mlemgroup/MlemMiddleware",
"state" : {
"revision" : "3221dd333c93e98ab3a3b8df996ecd7b4dc6ab9b",
"version" : "0.45.0"
"revision" : "6ce9ce56cb0e95b79e8a97e556952986f24c1498",
"version" : "0.46.0"
}
},
{
Expand Down
1 change: 1 addition & 0 deletions Mlem/App/Configuration/Icons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ enum Icons {
static let removeFill: String = "xmark.bin.fill"
static let restore: String = "arrow.up.bin"
static let restoreFill: String = "arrow.up.bin.fill"
static let purge: String = "burn"

// post sizes
static let postSizeSetting: String = "rectangle.expand.vertical"
Expand Down
10 changes: 10 additions & 0 deletions Mlem/App/Models/Action/ActionAppearance+StaticValues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ extension ActionAppearance {
)
}

static func purge(isInProgress: Bool = false) -> Self {
.init(
label: "Purge",
isInProgress: isInProgress,
isDestructive: true,
color: Palette.main.warning,
icon: Icons.purge
)
}

static func crossPost() -> Self {
.init(label: "Crosspost", color: Palette.main.accent, icon: Icons.crossPost)
}
Expand Down
2 changes: 1 addition & 1 deletion Mlem/App/Models/CommentWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class CommentWrapper: Identifiable, Comment2Providing {
}

func itemTree() -> [CommentTreeItem] {
if creator.blocked { return [] }
if shouldHideInFeed { return [] }
if collapsed { return [.comment(self)] }
var output: [CommentTreeItem] = children.reduce([.comment(self)]) { $0 + $1.itemTree() }
let directChildCount = children.reduce(commentCount) { $0 - $1.commentCount }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ extension Comment1Providing {

var isOwnComment: Bool { creatorId == api.myPerson?.id }

var shouldHideInFeed: Bool {
(creator_?.blocked ?? false) || purged
}

func showEditSheet() {
if let self = self as? any Comment2Providing {
NavigationModel.main.openSheet(.editComment(self.comment2, context: nil))
Expand Down Expand Up @@ -90,6 +94,11 @@ extension Comment1Providing {
if let self2, !isOwnComment {
self2.removeAction()
}
if api.isAdmin {
if let purgable = self as? any PurgableProviding {
purgable.purgeAction()
}
}
}

func shouldShowLoadingSymbol(for barConfiguration: CommentBarConfiguration? = nil) -> Bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// PersonContent+Extensions.swift
// Mlem
//
// Created by Sjmarf on 2024-10-31.
//

import MlemMiddleware

extension PersonContent {
var shouldHideInFeed: Bool {
switch wrappedValue {
case let .post(post): post.shouldHideInFeed
case let .comment(comment): comment.shouldHideInFeed
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ extension Post1Providing {
private var self2: (any Post2Providing)? { self as? any Post2Providing }

var isOwnPost: Bool { creatorId == api.myPerson?.id }

var shouldHideInFeed: Bool {
(creator_?.blocked ?? false) || (community_?.blocked ?? false) || (hidden_ ?? false) || purged
}

var canModerate: Bool {
api.myPerson?.moderates(communityId: communityId) ?? false || api.isAdmin
Expand Down Expand Up @@ -179,6 +183,11 @@ extension Post1Providing {
if let self2, !isOwnPost {
self2.removeAction()
}
if api.isAdmin {
if let purgable = self as? any PurgableProviding {
purgable.purgeAction()
}
}
}

// swiftlint:disable:next cyclomatic_complexity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// PurgableProviding+Extensions.swift
// Mlem
//
// Created by Sjmarf on 2024-10-27.
//

import Foundation
import MlemMiddleware

extension PurgableProviding {
func showPurgeSheet() {
NavigationModel.main.openSheet(.purge(self))
}

func purgeAction() -> BasicAction {
.init(
id: "purge\(uid)",
appearance: .purge(),
callback: (api.canInteract && api.isAdmin) ? showPurgeSheet : nil
)
}
}
74 changes: 74 additions & 0 deletions Mlem/App/Views/Pages/ContentPurgeEditorView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// ContentPurgeEditorView.swift
// Mlem
//
// Created by Sjmarf on 2024-10-26.
//

import MlemMiddleware
import SwiftUI

struct ContentPurgeEditorView: View {
@Environment(AppState.self) var appState
@Environment(Palette.self) var palette
@Environment(\.dismiss) var dismiss

let target: any PurgableProviding

@State var community: (any Community)?
@State var reason: String = ""
@FocusState var reasonFocused: Bool
@State var presentationSelection: PresentationDetent = .large

init(target: any PurgableProviding) {
self.target = target
self._community = .init(wrappedValue: (target as? any Interactable2Providing)?.community)
}

var body: some View {
CollapsibleSheetView(presentationSelection: $presentationSelection, canDismiss: reason.isEmpty) {
NavigationStack {
Form {
Section {
WarningView(
iconName: Icons.purge,
text: "Purged content is erased from the database and cannot be restored.",
inList: true
)
}
Section {
TextField("Reason (Optional)", text: $reason, axis: .vertical)
.focused($reasonFocused)
}
ReasonPickerView(reason: $reason, community: community)
}
.scrollDismissesKeyboard(.interactively)
.navigationBarTitleDisplayMode(.inline)
.navigationTitle("Purge")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Cancel") { dismiss() }
}
ToolbarItem(placement: .topBarTrailing) {
Button("Send", systemImage: Icons.send) {
Task {
await send()
}
}
}
}
}
.onAppear { reasonFocused = true }
}
}

func send() async {
do {
try await target.purge(reason: reason.isEmpty ? nil : reason)
HapticManager.main.play(haptic: .success, priority: .low)
dismiss()
} catch {
handleError(error)
}
}
}
2 changes: 2 additions & 0 deletions Mlem/App/Views/Shared/Navigation/NavigationPage+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ extension NavigationPage {
ReportEditorView(target: target.wrappedValue, community: community)
case let .remove(target):
ContentRemovalEditorView(target: target.wrappedValue)
case let .purge(target):
ContentPurgeEditorView(target: target.wrappedValue)
case let .post(post, scrollTargetedComment, communityContext, navigationNamespace):
PostPage(post: post, scrollTargetedComment: scrollTargetedComment?.wrappedValue)
.environment(\.communityContext, communityContext?.wrappedValue)
Expand Down
Loading

0 comments on commit afddd61

Please sign in to comment.