diff --git a/Mlem/App/Utility/Extensions/ApiClient+Extensions.swift b/Mlem/App/Utility/Extensions/ApiClient+Extensions.swift index cdca22ac9..6b8e124d5 100644 --- a/Mlem/App/Utility/Extensions/ApiClient+Extensions.swift +++ b/Mlem/App/Utility/Extensions/ApiClient+Extensions.swift @@ -19,4 +19,8 @@ extension ApiClient { } var canInteract: Bool { isActive && token != nil } + + var downvotesEnabled: Bool { + myInstance?.downvotesEnabled ?? true + } } diff --git a/Mlem/App/Utility/Extensions/Content Models/Comment1Providing+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/Comment1Providing+Extensions.swift index c2036813f..42715344f 100644 --- a/Mlem/App/Utility/Extensions/Content Models/Comment1Providing+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/Comment1Providing+Extensions.swift @@ -32,7 +32,9 @@ extension Comment1Providing { leadingActions: { if api.canInteract { upvoteAction(feedback: [.haptic]) - downvoteAction(feedback: [.haptic]) + if api.downvotesEnabled { + downvoteAction(feedback: [.haptic]) + } } }, trailingActions: { @@ -111,10 +113,10 @@ extension Comment1Providing { type: CommentBarConfiguration.ActionType, commentTreeTracker: CommentTreeTracker? = nil, communityContext: (any CommunityStubProviding)? = nil - ) -> any Action { + ) -> (any Action)? { switch type { case .upvote: upvoteAction(feedback: [.haptic]) - case .downvote: downvoteAction(feedback: [.haptic]) + case .downvote: api.downvotesEnabled ? downvoteAction(feedback: [.haptic]) : nil case .save: saveAction(feedback: [.haptic]) case .reply: replyAction(commentTreeTracker: commentTreeTracker) case .share: shareAction() @@ -127,21 +129,21 @@ extension Comment1Providing { func counter( type: CommentBarConfiguration.CounterType, commentTreeTracker: CommentTreeTracker? = nil - ) -> Counter { + ) -> Counter? { switch type { case .score: scoreCounter case .upvote: upvoteCounter - case .downvote: downvoteCounter + case .downvote: api.downvotesEnabled ? downvoteCounter : nil case .reply: replyCounter(commentTreeTracker: commentTreeTracker) } } - func readout(type: CommentBarConfiguration.ReadoutType) -> Readout { + func readout(type: CommentBarConfiguration.ReadoutType) -> Readout? { switch type { case .created: createdReadout - case .score: scoreReadout + case .score: api.downvotesEnabled ? scoreReadout : upvoteReadout case .upvote: upvoteReadout - case .downvote: downvoteReadout + case .downvote: api.downvotesEnabled ? downvoteReadout : nil case .comment: commentReadout } } diff --git a/Mlem/App/Utility/Extensions/Content Models/Interactable1Providing+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/Interactable1Providing+Extensions.swift index 9162d76ef..eb56e2fcc 100644 --- a/Mlem/App/Utility/Extensions/Content Models/Interactable1Providing+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/Interactable1Providing+Extensions.swift @@ -117,7 +117,7 @@ extension Interactable1Providing { .init( value: self2?.votes.total, leadingAction: upvoteAction(feedback: [.haptic]), - trailingAction: downvoteAction(feedback: [.haptic]) + trailingAction: api.downvotesEnabled ? downvoteAction(feedback: [.haptic]) : nil ) } @@ -140,10 +140,11 @@ extension Interactable1Providing { } func downvoteAction(feedback: Set = []) -> BasicAction { - .init( + let enabled = api.canInteract && api.downvotesEnabled + return .init( id: "downvote\(uid)", appearance: .downvote(isOn: self2?.votes.myVote ?? .none == .downvote), - callback: api.canInteract ? { self.self2?.toggleDownvoted(feedback: feedback) } : nil + callback: enabled ? { self.self2?.toggleDownvoted(feedback: feedback) } : nil ) } diff --git a/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift index de5799495..0b7c05820 100644 --- a/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift @@ -113,7 +113,9 @@ extension Post1Providing { leadingActions: { if api.canInteract { upvoteAction(feedback: [.haptic]) - downvoteAction(feedback: [.haptic]) + if api.downvotesEnabled { + downvoteAction(feedback: [.haptic]) + } } }, trailingActions: { @@ -198,10 +200,10 @@ extension Post1Providing { feedback: Set = [.haptic, .toast], commentTreeTracker: CommentTreeTracker? = nil, communityContext: (any CommunityStubProviding)? = nil - ) -> any Action { + ) -> (any Action)? { switch type { case .upvote: upvoteAction(feedback: feedback) - case .downvote: downvoteAction(feedback: feedback) + case .downvote: api.downvotesEnabled ? downvoteAction(feedback: feedback) : nil case .save: saveAction(feedback: feedback) case .reply: replyAction(commentTreeTracker: commentTreeTracker) case .share: shareAction() @@ -222,21 +224,21 @@ extension Post1Providing { func counter( type: PostBarConfiguration.CounterType, commentTreeTracker: CommentTreeTracker? = nil - ) -> Counter { + ) -> Counter? { switch type { case .score: scoreCounter case .upvote: upvoteCounter - case .downvote: downvoteCounter + case .downvote: api.downvotesEnabled ? downvoteCounter : nil case .reply: replyCounter(commentTreeTracker: commentTreeTracker) } } - func readout(type: PostBarConfiguration.ReadoutType) -> Readout { + func readout(type: PostBarConfiguration.ReadoutType) -> Readout? { switch type { case .created: createdReadout - case .score: scoreReadout + case .score: api.downvotesEnabled ? scoreReadout : upvoteReadout case .upvote: upvoteReadout - case .downvote: downvoteReadout + case .downvote: api.downvotesEnabled ? downvoteReadout : nil case .comment: commentReadout case .saved: savedReadout } diff --git a/Mlem/App/Utility/Extensions/Content Models/Reply1Providing+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/Reply1Providing+Extensions.swift index 346dcbbea..61394002c 100644 --- a/Mlem/App/Utility/Extensions/Content Models/Reply1Providing+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/Reply1Providing+Extensions.swift @@ -16,7 +16,9 @@ extension Reply1Providing { leadingActions: { if api.canInteract { upvoteAction(feedback: [.haptic]) - downvoteAction(feedback: [.haptic]) + if api.downvotesEnabled { + downvoteAction(feedback: [.haptic]) + } } }, trailingActions: { @@ -45,10 +47,10 @@ extension Reply1Providing { } } - func action(type: ReplyBarConfiguration.ActionType) -> any Action { + func action(type: ReplyBarConfiguration.ActionType) -> (any Action)? { switch type { case .upvote: upvoteAction(feedback: [.haptic]) - case .downvote: downvoteAction(feedback: [.haptic]) + case .downvote: api.downvotesEnabled ? downvoteAction(feedback: [.haptic]) : nil case .save: saveAction(feedback: [.haptic]) case .reply: replyAction() case .markRead: markReadAction(feedback: [.haptic]) @@ -57,21 +59,21 @@ extension Reply1Providing { } } - func counter(type: ReplyBarConfiguration.CounterType) -> Counter { + func counter(type: ReplyBarConfiguration.CounterType) -> Counter? { switch type { case .score: scoreCounter case .upvote: upvoteCounter - case .downvote: downvoteCounter + case .downvote: api.downvotesEnabled ? downvoteCounter : nil case .reply: replyCounter() } } - func readout(type: ReplyBarConfiguration.ReadoutType) -> Readout { + func readout(type: ReplyBarConfiguration.ReadoutType) -> Readout? { switch type { case .created: createdReadout - case .score: scoreReadout + case .score: api.downvotesEnabled ? scoreReadout : upvoteReadout case .upvote: upvoteReadout - case .downvote: downvoteReadout + case .downvote: api.downvotesEnabled ? downvoteReadout : nil case .comment: commentReadout } } diff --git a/Mlem/App/Views/Shared/InfoStackView.swift b/Mlem/App/Views/Shared/InfoStackView.swift index 7e274839d..ce4249ada 100644 --- a/Mlem/App/Views/Shared/InfoStackView.swift +++ b/Mlem/App/Views/Shared/InfoStackView.swift @@ -63,12 +63,12 @@ extension InfoStackView { } init(comment: any Comment1Providing, readouts: [CommentBarConfiguration.ReadoutType], showColor: Bool) { - self.readouts = readouts.map { comment.readout(type: $0) } + self.readouts = readouts.compactMap { comment.readout(type: $0) } self.showColor = showColor } init(reply: any Reply1Providing, readouts: [ReplyBarConfiguration.ReadoutType], showColor: Bool) { - self.readouts = readouts.map { reply.readout(type: $0) } + self.readouts = readouts.compactMap { reply.readout(type: $0) } self.showColor = showColor } } diff --git a/Mlem/App/Views/Shared/InteractionBar/InteractionBarView.swift b/Mlem/App/Views/Shared/InteractionBar/InteractionBarView.swift index 20dc6d7dc..34fef3102 100644 --- a/Mlem/App/Views/Shared/InteractionBar/InteractionBarView.swift +++ b/Mlem/App/Views/Shared/InteractionBar/InteractionBarView.swift @@ -34,7 +34,7 @@ struct InteractionBarView: View { commentTreeTracker: commentTreeTracker, communityContext: communityContext ) - self.readouts = configuration.readouts.map { post.readout(type: $0) } + self.readouts = configuration.readouts.compactMap { post.readout(type: $0) } } init( @@ -55,13 +55,13 @@ struct InteractionBarView: View { commentTreeTracker: commentTreeTracker, communityContext: communityContext ) - self.readouts = configuration.readouts.map { comment.readout(type: $0) } + self.readouts = configuration.readouts.compactMap { comment.readout(type: $0) } } init(reply: any Reply1Providing, configuration: ReplyBarConfiguration) { self.leading = .init(reply: reply, items: configuration.leading) self.trailing = .init(reply: reply, items: configuration.trailing) - self.readouts = configuration.readouts.map { reply.readout(type: $0) } + self.readouts = configuration.readouts.compactMap { reply.readout(type: $0) } } var body: some View { @@ -213,24 +213,22 @@ extension [EnrichedWidget] { commentTreeTracker: CommentTreeTracker?, communityContext: (any CommunityStubProviding)? ) { - self = items.map { item in + self = items.compactMap { item in switch item { case let .action(action): - return .action( - post.action( - type: action, - commentTreeTracker: commentTreeTracker, - communityContext: communityContext - ) - ) + if let action = post.action( + type: action, + commentTreeTracker: commentTreeTracker, + communityContext: communityContext + ) { + return .action(action) + } case let .counter(counter): - return .counter( - post.counter( - type: counter, - commentTreeTracker: commentTreeTracker - ) - ) + if let counter = post.counter(type: counter, commentTreeTracker: commentTreeTracker) { + return .counter(counter) + } } + return nil } } @@ -240,24 +238,25 @@ extension [EnrichedWidget] { commentTreeTracker: CommentTreeTracker?, communityContext: (any CommunityStubProviding)? ) { - self = items.map { item in + self = items.compactMap { item in switch item { case let .action(action): - return .action( - comment.action( - type: action, - commentTreeTracker: commentTreeTracker, - communityContext: communityContext - ) - ) + if let action = comment.action( + type: action, + commentTreeTracker: commentTreeTracker, + communityContext: communityContext + ) { + return .action(action) + } case let .counter(counter): - return .counter( - comment.counter( - type: counter, - commentTreeTracker: commentTreeTracker - ) - ) + if let counter = comment.counter( + type: counter, + commentTreeTracker: commentTreeTracker + ) { + return .counter(counter) + } } + return nil } } @@ -265,13 +264,18 @@ extension [EnrichedWidget] { reply: any Reply1Providing, items: [ReplyBarConfiguration.Item] ) { - self = items.map { item in + self = items.compactMap { item in switch item { case let .action(action): - return .action(reply.action(type: action)) + if let action = reply.action(type: action) { + return .action(action) + } case let .counter(counter): - return .counter(reply.counter(type: counter)) + if let counter = reply.counter(type: counter) { + return .counter(counter) + } } + return nil } } }