Skip to content

Commit

Permalink
added blocking users via a post
Browse files Browse the repository at this point in the history
  • Loading branch information
mani-sh-reddy committed Dec 6, 2023
1 parent 93d6259 commit b4f9385
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 24 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ All notable changes to this project will be documented in this file.
## [Unreleased]

### Added
- Added a warning to notify users about errors performing actions outside of home instance

- Blocking users via a post
- Warning to notify users about errors performing actions outside of home instance
### Misc

- Removed `Shiny` package due to lag
Expand Down
16 changes: 8 additions & 8 deletions Lunar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
3C3E75F42B210AF900F25F7D /* PulseWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E75F32B210AF900F25F7D /* PulseWriter.swift */; };
3C3E75F62B21102200F25F7D /* RealmWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E75F52B21102200F25F7D /* RealmWriter.swift */; };
3C3E75F82B21158100F25F7D /* GenerateHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E75F72B21158100F25F7D /* GenerateHeaders.swift */; };
3C3E75FA2B21239400F25F7D /* BlockUserSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E75F92B21239400F25F7D /* BlockUserSender.swift */; };
3C3E75FC2B212F2600F25F7D /* BlockUserResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E75FB2B212F2600F25F7D /* BlockUserResponseModel.swift */; };
3C41EEC82AFECEF200F47931 /* CheckBiometricType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C41EEC72AFECEF200F47931 /* CheckBiometricType.swift */; };
3C42AD1A2A8038300056AFBC /* KbinCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C42AD192A8038300056AFBC /* KbinCommentsView.swift */; };
3C42AD1C2A803AE50056AFBC /* KbinCommentsFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C42AD1B2A803AE50056AFBC /* KbinCommentsFetcher.swift */; };
Expand Down Expand Up @@ -365,6 +367,8 @@
3C3E75F32B210AF900F25F7D /* PulseWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PulseWriter.swift; sourceTree = "<group>"; };
3C3E75F52B21102200F25F7D /* RealmWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmWriter.swift; sourceTree = "<group>"; };
3C3E75F72B21158100F25F7D /* GenerateHeaders.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateHeaders.swift; sourceTree = "<group>"; };
3C3E75F92B21239400F25F7D /* BlockUserSender.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockUserSender.swift; sourceTree = "<group>"; };
3C3E75FB2B212F2600F25F7D /* BlockUserResponseModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockUserResponseModel.swift; sourceTree = "<group>"; };
3C41EEC72AFECEF200F47931 /* CheckBiometricType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckBiometricType.swift; sourceTree = "<group>"; };
3C42AD192A8038300056AFBC /* KbinCommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KbinCommentsView.swift; sourceTree = "<group>"; };
3C42AD1B2A803AE50056AFBC /* KbinCommentsFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KbinCommentsFetcher.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -668,6 +672,7 @@
3C4D42A72A8D0FD1003B6F1D /* VoteSender.swift */,
3CC3E4222ADC4A2600F7F9A9 /* ImageSender.swift */,
3C6BBF712A910F6100312E2B /* SubscriptionActionSender.swift */,
3C3E75F92B21239400F25F7D /* BlockUserSender.swift */,
3C9E548B2A94A3DC0093DDC7 /* CommentSender.swift */,
3CC3E42C2ADD6EBA00F7F9A9 /* PostSender.swift */,
3CA8A0C22AE570E200EEABD3 /* PostsFetcher.swift */,
Expand All @@ -682,13 +687,6 @@
path = Fetchers;
sourceTree = "<group>";
};
3C4D42A62A8D0FB3003B6F1D /* DataSenders */ = {
isa = PBXGroup;
children = (
);
path = DataSenders;
sourceTree = "<group>";
};
3C4F09F32A54399F009DF8AB = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -735,7 +733,6 @@
3CCAE1842A6ADDE20040EE12 /* Comment View */,
3C3E75F12B20FF1300F25F7D /* Fetchers */,
3CE237332AA4D157000F1D20 /* Common Views */,
3C4D42A62A8D0FB3003B6F1D /* DataSenders */,
3CA5C4082A57443200BF8F1B /* DataModels */,
3C96EA582A79147C00753199 /* Debugging Views */,
3CC3E4102ADBE39700F7F9A9 /* Defaults */,
Expand Down Expand Up @@ -860,6 +857,7 @@
3CC3E4302ADDCE1200F7F9A9 /* CreatePostResponseModel.swift */,
3CC3E4242ADC556300F7F9A9 /* ImageUploadResponseModel.swift */,
3C6BBF732A91108A00312E2B /* SubscribeResponseModel.swift */,
3C3E75FB2B212F2600F25F7D /* BlockUserResponseModel.swift */,
3C9E54992A954C060093DDC7 /* CommentResponseModel.swift */,
3C1A3F5C2A73BC9F00898FC6 /* CredentialsModel.swift */,
3CC3E4322ADDCF7E00F7F9A9 /* ErrorResponseModel.swift */,
Expand Down Expand Up @@ -1397,6 +1395,7 @@
3CECCE252AAE68E80017A605 /* LocalUserProperties.swift in Sources */,
3C87A36A2A9F9C4E0029C18F /* ForceAppearance.swift in Sources */,
3C5ECB2C2A7676B5002BA561 /* PasswordFieldView.swift in Sources */,
3C3E75FA2B21239400F25F7D /* BlockUserSender.swift in Sources */,
3CB046F82ADB2A220011BFEC /* PersonModel.swift in Sources */,
3CA5C40A2A574FF500BF8F1B /* PostModel.swift in Sources */,
3CB9C72B2AA2423400FB5A10 /* CommentObject.swift in Sources */,
Expand Down Expand Up @@ -1476,6 +1475,7 @@
3CECCE1C2AADBFFA0017A605 /* ColorTesterView.swift in Sources */,
3CC3E4232ADC4A2600F7F9A9 /* ImageSender.swift in Sources */,
3C808E242A9B6DAD008FA62E /* SettingsDevOptionsView.swift in Sources */,
3C3E75FC2B212F2600F25F7D /* BlockUserResponseModel.swift in Sources */,
3C42AD1A2A8038300056AFBC /* KbinCommentsView.swift in Sources */,
3C6299D12A751A5900BE2A9F /* TextExtension.swift in Sources */,
3CF3B8FD2A90188D001C08B5 /* CommentMetadataView.swift in Sources */,
Expand Down
4 changes: 4 additions & 0 deletions Lunar/Common Views/AllSymbols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class AllSymbols {
SFSafeSymbols.SFSymbol.slashCircle
}

var blockContextIcon: SFSafeSymbols.SFSymbol {
SFSafeSymbols.SFSymbol.xmarkCircle
}

var upvoteContextIcon: SFSafeSymbols.SFSymbol {
SFSafeSymbols.SFSymbol.arrowUpCircle
}
Expand Down
1 change: 1 addition & 0 deletions Lunar/DataModels/AccountModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ struct AccountModel: Codable, Hashable, Defaults.Serializable {
var postCount: Int = 0
var commentScore: Int = 0
var commentCount: Int = 0
var instance: String { URLParser.extractDomain(from: actorID) }
}
18 changes: 18 additions & 0 deletions Lunar/DataModels/BlockUserResponseModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// BlockUserResponseModel.swift
// Lunar
//
// Created by Mani on 19/08/2023.
//

import Foundation

struct BlockUserResponseModel: Codable {
let person: PersonObject?
let blocked: Bool

enum CodingKeys: String, CodingKey {
case person = "person_view"
case blocked
}
}
75 changes: 75 additions & 0 deletions Lunar/Fetchers/BlockUserSender.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// BlockUserSender.swift
// Lunar
//
// Created by Mani on 16/08/2023.
//

import Alamofire
import Defaults
import Foundation
import Pulse
import SwiftUI

class BlockUserSender: ObservableObject {
@Default(.activeAccount) var activeAccount
@Default(.appBundleID) var appBundleID

private var personID: Int
private var block: Bool

init(
personID: Int,
block: Bool
) {
self.personID = personID
self.block = block
}

func blockUser(completion: @escaping (Int?, Bool?, String?) -> Void) {
let JSONparameters =
[
"block": block,
"person_id": personID,
"auth": JWT().getJWTForActiveAccount() as Any,
] as [String: Any]

let endpoint = "https://\(activeAccount.instance)/api/v3/user/block"

AF.request(
endpoint,
method: .post,
parameters: JSONparameters,
encoding: JSONEncoding.default,
headers: GenerateHeaders().generate()
)
.validate(statusCode: 200 ..< 300)
.responseDecodable(of: BlockUserResponseModel.self) { response in

PulseWriter().write(response, EndpointParameters(endpointPath: endpoint), .post)

print(response.request ?? "")
switch response.result {
case let .success(result):
print(result.blocked)
let response = String(response.response?.statusCode ?? 0)
let userIsBlockedResponse = result.blocked
let personID = result.person?.person.id

completion(personID, userIsBlockedResponse, response)

case let .failure(error):
if let data = response.data,
let fetchError = try? JSONDecoder().decode(ErrorResponseModel.self, from: data)
{
print("BlockUserSender ERROR: \(fetchError.error)")
completion(nil, nil, fetchError.error)
} else {
let errorDescription = String(describing: error.errorDescription)
print("BlockUserSender JSON DECODE ERROR: \(error): \(errorDescription)")
completion(nil, nil, error.errorDescription)
}
}
}
}
}
31 changes: 22 additions & 9 deletions Lunar/Fetchers/PulseWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SwiftUI

class PulseWriter {
@Default(.networkInspectorEnabled) var networkInspectorEnabled
@Default(.selectedInstance) var selectedInstance

let pulse = Pulse.LoggerStore.shared

Expand All @@ -23,14 +24,26 @@ class PulseWriter {
) {
guard networkInspectorEnabled else { return }

pulse.storeRequest(
try! URLRequest(
url: EndpointBuilder(parameters: parameters).build(redact: true),
method: method
),
response: response.response,
error: response.error,
data: response.data
)
if method == .get {
pulse.storeRequest(
try! URLRequest(
url: EndpointBuilder(parameters: parameters).build(redact: true),
method: method
),
response: response.response,
error: response.error,
data: response.data
)
} else if method == .post {
pulse.storeRequest(
try! URLRequest(
url: URL(string: "https://\(selectedInstance)\(parameters.endpointPath)")!,
method: method
),
response: response.response,
error: response.error,
data: response.data
)
}
}
}
3 changes: 1 addition & 2 deletions Lunar/Fetchers/RealmWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ class RealmWriter {
) {
try! realm.write {
for post in posts {

guard !post.creatorBlocked else { return }

let realmPost = RealmPost(
postID: post.post.id,
postName: post.post.name,
Expand Down
2 changes: 1 addition & 1 deletion Lunar/Fetchers/SubscriptionActionSender.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SubscriptionActionSender: ObservableObject {
)
.validate(statusCode: 200 ..< 300)
.responseDecodable(of: SubscribeResponseModel.self) { response in

PulseWriter().write(response, EndpointParameters(endpointPath: endpoint), .post)

print(response.request ?? "")
Expand Down
39 changes: 39 additions & 0 deletions Lunar/Post Views/PostItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct PostItem: View {

@State var showSafari: Bool = false
@State var subscribeAlertPresented: Bool = false
@State var blockUserAlertPresented: Bool = false

let hapticsLight = UIImpactFeedbackGenerator(style: .light)

Expand Down Expand Up @@ -110,6 +111,15 @@ struct PostItem: View {
hideButton
minimiseButton
shareButton
blockUserButton
}
}

var blockUserButton: some View {
Button {
blockUserAlertPresented = true
} label: {
Label("Block User", systemSymbol: AllSymbols().blockContextIcon)
}
}

Expand Down Expand Up @@ -210,6 +220,25 @@ struct PostItem: View {
} message: {
Text("\(post.communityName)@\(URLParser.extractDomain(from: post.communityActorID))")
}
.confirmationDialog("", isPresented: $blockUserAlertPresented) {
blockUserConfirmationDialogButtons
} message: {
Text("Block User \(URLParser.buildFullUsername(from: post.personActorID))")
}
}

@ViewBuilder
var blockUserConfirmationDialogButtons: some View {
Button("Block") {
blockUserAction()
}
Button("Block and Report") {
blockUserAction()
// reportUserAction()
}
Button("Dismiss", role: .cancel) {
blockUserAlertPresented = false
}
}

var postTitle: some View {
Expand Down Expand Up @@ -385,4 +414,14 @@ struct PostItem: View {
}
}
}

func blockUserAction() {
if let personID = post.personID {
BlockUserSender(personID: personID, block: true).blockUser { _, userIsBlockedResponse, _ in
if userIsBlockedResponse == true {
RealmThawFunctions().deleteAction(post: post)
}
}
}
}
}
6 changes: 3 additions & 3 deletions Lunar/Settings Views/SettingsAccountView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import SwiftUI
struct SettingsAccountView: View {
@Default(.activeAccount) var activeAccount
@Default(.selectedInstance) var selectedInstance

@State var showingPopover: Bool = false
@State var isPresentingConfirm: Bool = false
@State var logoutAllUsersButtonClicked: Bool = false
Expand All @@ -24,7 +24,7 @@ struct SettingsAccountView: View {

var body: some View {
List {
if !activeAccount.actorID.isEmpty && selectedInstance != URLParser.extractDomain(from: activeAccount.actorID) {
if !activeAccount.actorID.isEmpty, selectedInstance != URLParser.extractDomain(from: activeAccount.actorID) {
Section {
VStack(spacing: 10) {
Text("Note: If the current user's home instance differs from the selected instance, errors may occur while attempting actions such as voting, replying, or blocking.")
Expand All @@ -42,7 +42,7 @@ struct SettingsAccountView: View {
.font(.caption)
.foregroundStyle(.gray)
}

Section {
if isLoginFlowComplete {
LoggedInUsersListView()
Expand Down
13 changes: 13 additions & 0 deletions Lunar/Tools/RealmThawFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ class RealmThawFunctions {
}
}

func deleteAction(post: RealmPost) {
let thawedPost = post.thaw()
if thawedPost?.isInvalidated == false {
let thawedRealm = thawedPost!.realm!
try! thawedRealm.write {
if let thawedPost {
thawedRealm.delete(thawedPost)
}
}
}
hapticsSoft.impactOccurred(intensity: 0.5)
}

func hideAction(post: RealmPost) {
let realm = try! Realm()
try! realm.write {
Expand Down
5 changes: 5 additions & 0 deletions Lunar/Tools/Utilities/URLParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ enum URLParser {

return components.penultimate() ?? ""
}

/// "https://lemmy.world/c/mani" ==> _mani@lemmy.world_
static func buildFullUsername(from url: String) -> String {
"\(extractUsername(from: url))@\(extractDomain(from: url))"
}
}

0 comments on commit b4f9385

Please sign in to comment.