Skip to content

Commit

Permalink
Communication: Integrate Profile Picture/Info into channel member l…
Browse files Browse the repository at this point in the history
…ist (#191)

* Add profile pictures to channel member list

* Integrate channel info sheet with profile info sheet
  • Loading branch information
anian03 authored Oct 21, 2024
1 parent 2371191 commit 9306822
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ class ProfileViewModel {
let role: UserRole?
private var login: String?
let course: Course
var actions: [ProfileInfoSheetAction]

init(course: Course, user: ConversationUser, role: UserRole?) {
init(course: Course, user: ConversationUser, role: UserRole?, actions: [ProfileInfoSheetAction]) {
self.course = course
self.user = user
self.role = role
self.actions = actions
}

// We can only create a conversation if we have the user's login
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,27 +134,32 @@ private extension ConversationInfoSheetView {
} content: { members in
ForEach(members, id: \.id) { member in
if let name = member.name {
Menu {
if let login = member.login,
!(conversation.baseConversation is OneToOneChat) {
Button(R.string.localizable.sendMessage(), systemImage: "bubble.left.fill") {
viewModel.sendMessageToUser(with: login, navigationController: navigationController) {
dismiss()
}
}
}
Divider()
removeUserButton(member: member)
} label: {
HStack {
Text(name)
Spacer()
if UserSessionFactory.shared.user?.login == member.login {
Chip(text: R.string.localizable.youLabel(), backgroundColor: .Artemis.artemisBlue)
}
HStack {
ProfilePictureView(
user: member,
role: nil,
course: viewModel.course,
size: 25,
actions: [
ProfileInfoSheetAction(
title: R.string.localizable.removeUserButtonLabel(),
iconName: "person.badge.minus",
isDestructive: true,
isEnabled: UserSessionFactory.shared.user?.login != member.login && viewModel.canRemoveUsers,
action: {
viewModel.isLoading = true
Task {
await viewModel.removeMemberFromConversation(member: member)
viewModel.isLoading = false
}
})
])
Text(name)
Spacer()
if UserSessionFactory.shared.user?.login == member.login {
Chip(text: R.string.localizable.youLabel(), backgroundColor: .Artemis.artemisBlue)
}
}
.buttonStyle(.plain)
.swipeActions(edge: .trailing) {
removeUserButton(member: member)
}
Expand All @@ -180,6 +185,7 @@ private extension ConversationInfoSheetView {
viewModel.isLoading = false
}
}
.foregroundStyle(.red)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import SwiftUI

struct ProfilePictureView: View {
@State private var viewModel: ProfileViewModel
let size: CGFloat

init(user: ConversationUser, role: UserRole?, course: Course) {
self._viewModel = State(initialValue: ProfileViewModel(course: course, user: user, role: role))
init(user: ConversationUser, role: UserRole?, course: Course, size: CGFloat = 44, actions: [ProfileInfoSheetAction] = []) {
self._viewModel = State(initialValue: ProfileViewModel(course: course, user: user, role: role, actions: actions))
self.size = size
}

var body: some View {
Expand All @@ -26,10 +28,10 @@ struct ProfilePictureView: View {
DefaultProfilePictureView(viewModel: viewModel)
}
} else {
DefaultProfilePictureView(viewModel: viewModel)
DefaultProfilePictureView(viewModel: viewModel, font: size < 35 ? .caption.bold() : .headline.bold())
}
}
.frame(width: 44, height: 44)
.frame(width: size, height: size)
.clipShape(.rect(cornerRadius: .m))
.sheet(isPresented: $viewModel.showProfileSheet) {
ProfileInfoSheet(viewModel: viewModel)
Expand Down Expand Up @@ -121,6 +123,15 @@ struct ProfileInfoSheet: View {
dismiss()
}
}
ForEach(viewModel.actions, id: \.hashValue) { action in
if action.isEnabled {
Button(action.title, systemImage: action.iconName) {
action.action()
dismiss()
}
.foregroundStyle(action.isDestructive ? Color.red : Color.blue)
}
}
}
}
}
Expand Down Expand Up @@ -165,3 +176,20 @@ struct ProfileInfoSheet: View {
}
}
}

struct ProfileInfoSheetAction: Hashable, Equatable {
static func == (lhs: ProfileInfoSheetAction, rhs: ProfileInfoSheetAction) -> Bool {
lhs.hashValue == rhs.hashValue
}

let title: String
let iconName: String
let isDestructive: Bool
let isEnabled: Bool
let action: () -> Void

func hash(into hasher: inout Hasher) {
hasher.combine(title)
hasher.combine(iconName)
}
}

0 comments on commit 9306822

Please sign in to comment.