Skip to content

Commit

Permalink
Added blocked users example in the demo app (#571)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmitrevski authored Aug 2, 2024
1 parent 42f5672 commit 4e13e10
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 7 deletions.
2 changes: 1 addition & 1 deletion DemoAppSwiftUI/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
#endif

let utils = Utils(
messageListConfig: MessageListConfig(dateIndicatorPlacement: .messageList),
messageListConfig: MessageListConfig(dateIndicatorPlacement: .messageList, userBlockingEnabled: true),
composerConfig: ComposerConfig(isVoiceRecordingEnabled: true)
)
streamChat = StreamChat(chatClient: chatClient, utils: utils)
Expand Down
50 changes: 50 additions & 0 deletions DemoAppSwiftUI/BlockedUsersView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Copyright © 2024 Stream.io Inc. All rights reserved.
//

import StreamChatSwiftUI
import SwiftUI

struct BlockedUsersView: View {

@StateObject var viewModel = BlockedUsersViewModel()

var body: some View {
ZStack {
if !viewModel.blockedUsers.isEmpty {
List {
ForEach(viewModel.blockedUsers) { blockedUser in
HStack {
MessageAvatarView(avatarURL: blockedUser.imageURL, size: .init(width: 48, height: 48))
Text(blockedUser.name ?? blockedUser.id)
.font(.headline)
Spacer()
}
.listRowSeparator(.hidden)
}
.onDelete(perform: delete)
}
.toolbar {
EditButton()
}
.listStyle(.plain)
} else {
VStack {
Text("There are currently no blocked users.")
.padding()
Spacer()
}
}
}
.onAppear {
viewModel.loadBlockedUsers()
}
.navigationTitle("Blocked Users")
}

func delete(at offsets: IndexSet) {
if let first = offsets.first, first < viewModel.blockedUsers.count {
viewModel.unblock(user: viewModel.blockedUsers[first])
}
}
}
48 changes: 48 additions & 0 deletions DemoAppSwiftUI/BlockedUsersViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Copyright © 2024 Stream.io Inc. All rights reserved.
//

import StreamChat
import StreamChatSwiftUI
import SwiftUI

class BlockedUsersViewModel: ObservableObject {

@Injected(\.chatClient) var chatClient

@Published var blockedUsers = [ChatUser]()

private let currentUserController: CurrentChatUserController

init() {
currentUserController = InjectedValues[\.chatClient].currentUserController()
currentUserController.synchronize()
}

func loadBlockedUsers() {
let blockedUserIds = currentUserController.currentUser?.blockedUserIds ?? []
for blockedUserId in blockedUserIds {
if let user = currentUserController.dataStore.user(id: blockedUserId) {
blockedUsers.append(user)
} else {
let controller = chatClient.userController(userId: blockedUserId)
controller.synchronize { [weak self] _ in
if let user = controller.user {
self?.blockedUsers.append(user)
}
}
}
}
}

func unblock(user: ChatUser) {
let unblockController = chatClient.userController(userId: user.id)
unblockController.unblock { [weak self] error in
if error == nil {
self?.blockedUsers.removeAll { blocked in
blocked.id == user.id
}
}
}
}
}
27 changes: 24 additions & 3 deletions DemoAppSwiftUI/CustomChannelHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct CustomChannelHeader: ToolbarContent {
var title: String
var currentUserController: CurrentChatUserController
@Binding var isNewChatShown: Bool
@Binding var logoutAlertShown: Bool
@Binding var actionsPopupShown: Bool

@MainActor
public var body: some ToolbarContent {
Expand All @@ -39,7 +39,7 @@ public struct CustomChannelHeader: ToolbarContent {
}
ToolbarItem(placement: .navigationBarLeading) {
Button {
logoutAlertShown = true
actionsPopupShown = true
} label: {
StreamLazyImage(url: currentUserController.currentUser?.imageURL)
}
Expand All @@ -55,6 +55,8 @@ struct CustomChannelModifier: ChannelListHeaderViewModifier {

@State var isNewChatShown = false
@State var logoutAlertShown = false
@State var actionsPopupShown = false
@State var blockedUsersShown = false

func body(content: Content) -> some View {
ZStack {
Expand All @@ -63,9 +65,15 @@ struct CustomChannelModifier: ChannelListHeaderViewModifier {
title: title,
currentUserController: chatClient.currentUserController(),
isNewChatShown: $isNewChatShown,
logoutAlertShown: $logoutAlertShown
actionsPopupShown: $actionsPopupShown
)
}

NavigationLink(isActive: $blockedUsersShown) {
BlockedUsersView()
} label: {
EmptyView()
}

NavigationLink(isActive: $isNewChatShown) {
NewChatView(isNewChatShown: $isNewChatShown)
Expand All @@ -90,6 +98,19 @@ struct CustomChannelModifier: ChannelListHeaderViewModifier {
secondaryButton: .cancel()
)
}
.confirmationDialog("", isPresented: $actionsPopupShown) {
Button("Blocked users") {
blockedUsersShown = true
}

Button("Logout") {
logoutAlertShown = true
}

Button("Cancel", role: .cancel) {}
} message: {
Text("Select an action")
}
}
}
}
14 changes: 11 additions & 3 deletions StreamChatSwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@
846AD4D2284F89B10074A0DD /* StreamChatTestTools in Frameworks */ = {isa = PBXBuildFile; productRef = 846AD4D1284F89B10074A0DD /* StreamChatTestTools */; };
846AD4D4284F95710074A0DD /* CustomChannelHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846AD4D3284F95710074A0DD /* CustomChannelHeader.swift */; };
846B15F42817E7630017F7A1 /* ChatChannelInfoViewModel_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B15F32817E7630017F7A1 /* ChatChannelInfoViewModel_Tests.swift */; };
846B8E2C2C5B8117006A6249 /* BlockedUsersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B8E2B2C5B8117006A6249 /* BlockedUsersView.swift */; };
846B8E2E2C5B8130006A6249 /* BlockedUsersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */; };
846D6564279FF0800094B36E /* ReactionUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846D6563279FF0800094B36E /* ReactionUserView.swift */; };
847110B628611033004A46D6 /* MessageActions_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840008BA27E8D64A00282D88 /* MessageActions_Tests.swift */; };
847305BB28241D8D004AC770 /* ChatChannelHeader_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847305BA28241D8D004AC770 /* ChatChannelHeader_Tests.swift */; };
Expand Down Expand Up @@ -885,6 +887,8 @@
8469592E29BB235400134EA0 /* LazyImageExtensions_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyImageExtensions_Tests.swift; sourceTree = "<group>"; };
846AD4D3284F95710074A0DD /* CustomChannelHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomChannelHeader.swift; sourceTree = "<group>"; };
846B15F32817E7630017F7A1 /* ChatChannelInfoViewModel_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelInfoViewModel_Tests.swift; sourceTree = "<group>"; };
846B8E2B2C5B8117006A6249 /* BlockedUsersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersView.swift; sourceTree = "<group>"; };
846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersViewModel.swift; sourceTree = "<group>"; };
846D6563279FF0800094B36E /* ReactionUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionUserView.swift; sourceTree = "<group>"; };
847305BA28241D8D004AC770 /* ChatChannelHeader_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelHeader_Tests.swift; sourceTree = "<group>"; };
847305BC28243D25004AC770 /* WebView_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView_Tests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1571,6 +1575,8 @@
8451617F2AE7C4E2000A9230 /* WhatsAppChannelHeader.swift */,
8417AE912ADEDB6400445021 /* UserRepository.swift */,
8413C4542B4409B600190AF4 /* PinChannelHelpers.swift */,
846B8E2B2C5B8117006A6249 /* BlockedUsersView.swift */,
846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */,
84EDBC36274FE5CD0057218D /* Localizable.strings */,
8465FCCA27468B7500AF091E /* Info.plist */,
8465FCC227468B6A00AF091E /* Assets.xcassets */,
Expand Down Expand Up @@ -2920,6 +2926,7 @@
files = (
8465FDDD2747A14700AF091E /* CustomComposerAttachmentView.swift in Sources */,
84335016274BABF3007A1B81 /* NewChatView.swift in Sources */,
846B8E2C2C5B8117006A6249 /* BlockedUsersView.swift in Sources */,
84335018274BAD4B007A1B81 /* NewChatViewModel.swift in Sources */,
84B288CD274C544B00DD090B /* CreateGroupView.swift in Sources */,
845161802AE7C4E2000A9230 /* WhatsAppChannelHeader.swift in Sources */,
Expand All @@ -2930,6 +2937,7 @@
8465FCDE274694D200AF091E /* CustomChannelHeader.swift in Sources */,
8451617E2AE7B093000A9230 /* AppleMessageComposerView.swift in Sources */,
8413C4552B4409B600190AF4 /* PinChannelHelpers.swift in Sources */,
846B8E2E2C5B8130006A6249 /* BlockedUsersViewModel.swift in Sources */,
84B288D3274D23AF00DD090B /* LoginView.swift in Sources */,
84B288D5274D286500DD090B /* LoginViewModel.swift in Sources */,
8465FCBF27468B6900AF091E /* DemoAppSwiftUIApp.swift in Sources */,
Expand Down Expand Up @@ -3129,7 +3137,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -3564,7 +3572,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -3599,7 +3607,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down

0 comments on commit 4e13e10

Please sign in to comment.