mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
ios: new chat sheet & info views action buttons improvements (#4582)
This commit is contained in:
@@ -148,21 +148,22 @@ struct ChatInfoView: View {
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
searchButton()
|
||||
Spacer()
|
||||
AudioCallButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
Spacer()
|
||||
VideoButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
Spacer()
|
||||
muteButton()
|
||||
Spacer()
|
||||
GeometryReader { g in
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
let buttonWidth = g.size.width / 4
|
||||
searchButton(width: buttonWidth)
|
||||
AudioCallButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) }, width: buttonWidth)
|
||||
VideoButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) }, width: buttonWidth)
|
||||
muteButton(width: buttonWidth)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.padding(.trailing)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: infoViewActionButtonHeight)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 8))
|
||||
|
||||
if let customUserProfile = customUserProfile {
|
||||
Section(header: Text("Incognito").foregroundColor(theme.colors.secondary)) {
|
||||
HStack {
|
||||
@@ -392,8 +393,8 @@ struct ChatInfoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func searchButton() -> some View {
|
||||
InfoViewActionButtonLayout(image: "magnifyingglass", title: "search")
|
||||
private func searchButton(width: CGFloat) -> some View {
|
||||
InfoViewActionButtonLayout(image: "magnifyingglass", title: "search", width: width)
|
||||
.onTapGesture {
|
||||
dismiss()
|
||||
onSearch()
|
||||
@@ -401,10 +402,11 @@ struct ChatInfoView: View {
|
||||
.disabled(!contact.ready || chat.chatItems.isEmpty)
|
||||
}
|
||||
|
||||
private func muteButton() -> some View {
|
||||
private func muteButton(width: CGFloat) -> some View {
|
||||
InfoViewActionButtonLayout(
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash" : "speaker.wave.2",
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute"
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash.fill" : "speaker.wave.2.fill",
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute",
|
||||
width: width
|
||||
)
|
||||
.onTapGesture {
|
||||
toggleNotifications(chat, enableNtfs: !chat.chatInfo.ntfsEnabled)
|
||||
@@ -622,15 +624,17 @@ struct AudioCallButton: View {
|
||||
var chat: Chat
|
||||
var contact: Contact
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
CallButton(
|
||||
chat: chat,
|
||||
contact: contact,
|
||||
image: "phone",
|
||||
image: "phone.fill",
|
||||
title: "call",
|
||||
mediaType: .audio,
|
||||
showAlert: showAlert
|
||||
showAlert: showAlert,
|
||||
width: width
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -639,15 +643,17 @@ struct VideoButton: View {
|
||||
var chat: Chat
|
||||
var contact: Contact
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
CallButton(
|
||||
chat: chat,
|
||||
contact: contact,
|
||||
image: "video",
|
||||
image: "video.fill",
|
||||
title: "video",
|
||||
mediaType: .video,
|
||||
showAlert: showAlert
|
||||
showAlert: showAlert,
|
||||
width: width
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -659,11 +665,12 @@ private struct CallButton: View {
|
||||
var title: LocalizedStringKey
|
||||
var mediaType: CallMediaType
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
let canCall = contact.ready && contact.active && chat.chatInfo.featureEnabled(.calls) && ChatModel.shared.activeCall == nil
|
||||
|
||||
InfoViewActionButtonLayout(image: image, title: title, disabledLook: !canCall)
|
||||
InfoViewActionButtonLayout(image: image, title: title, disabledLook: !canCall, width: width)
|
||||
.onTapGesture {
|
||||
if canCall {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
@@ -733,10 +740,15 @@ private struct CallButton: View {
|
||||
}
|
||||
}
|
||||
|
||||
let infoViewActionButtonWidth: CGFloat = 83
|
||||
|
||||
let infoViewActionButtonHeight: CGFloat = 60
|
||||
|
||||
struct InfoViewActionButtonLayout: View {
|
||||
var image: String
|
||||
var title: LocalizedStringKey
|
||||
var disabledLook: Bool = false
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 4) {
|
||||
@@ -750,8 +762,8 @@ struct InfoViewActionButtonLayout: View {
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.foregroundColor(.accentColor)
|
||||
.background(Color(.secondarySystemGroupedBackground))
|
||||
.cornerRadius(12.0)
|
||||
.frame(width: 82, height: 56)
|
||||
.cornerRadius(10.0)
|
||||
.frame(width: width, height: infoViewActionButtonHeight)
|
||||
.disabled(disabledLook)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,20 +71,13 @@ struct GroupChatInfoView: View {
|
||||
groupInfoHeader()
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
searchButton()
|
||||
if groupInfo.canAddMembers {
|
||||
Spacer()
|
||||
addMembersActionButton()
|
||||
}
|
||||
Spacer()
|
||||
muteButton()
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
infoActionButtons()
|
||||
.padding(.horizontal)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: infoViewActionButtonHeight)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
|
||||
Section {
|
||||
if groupInfo.canEdit {
|
||||
@@ -215,6 +208,16 @@ struct GroupChatInfoView: View {
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
|
||||
func infoActionButtons() -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
searchButton()
|
||||
if groupInfo.canAddMembers {
|
||||
addMembersActionButton()
|
||||
}
|
||||
muteButton()
|
||||
}
|
||||
}
|
||||
|
||||
private func searchButton() -> some View {
|
||||
InfoViewActionButtonLayout(image: "magnifyingglass", title: "search")
|
||||
.onTapGesture {
|
||||
@@ -237,12 +240,13 @@ struct GroupChatInfoView: View {
|
||||
} label: {
|
||||
EmptyView()
|
||||
}
|
||||
.frame(width: 1, height: 1)
|
||||
.hidden()
|
||||
}
|
||||
.disabled(!groupInfo.ready)
|
||||
} else {
|
||||
ZStack {
|
||||
InfoViewActionButtonLayout(image: "person.badge.plus", title: "invite")
|
||||
InfoViewActionButtonLayout(image: "person.fill.badge.plus", title: "invite")
|
||||
.onTapGesture {
|
||||
addMembersNavLinkActive = true
|
||||
}
|
||||
@@ -252,6 +256,7 @@ struct GroupChatInfoView: View {
|
||||
} label: {
|
||||
EmptyView()
|
||||
}
|
||||
.frame(width: 1, height: 1)
|
||||
.hidden()
|
||||
}
|
||||
.disabled(!groupInfo.ready)
|
||||
@@ -260,7 +265,7 @@ struct GroupChatInfoView: View {
|
||||
|
||||
private func muteButton() -> some View {
|
||||
InfoViewActionButtonLayout(
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash" : "speaker.wave.2",
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash.fill" : "speaker.wave.2.fill",
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute"
|
||||
)
|
||||
.onTapGesture {
|
||||
|
||||
@@ -87,8 +87,11 @@ struct GroupMemberInfoView: View {
|
||||
|
||||
infoActionButtons(member)
|
||||
.padding(.horizontal)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: infoViewActionButtonHeight)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
|
||||
if member.memberActive {
|
||||
Section {
|
||||
@@ -251,41 +254,28 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
|
||||
func infoActionButtons(_ member: GroupMember) -> some View {
|
||||
HStack {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let contactId = member.memberContactId, let (chat, contact) = knownDirectChat(contactId) {
|
||||
Spacer()
|
||||
knownDirectChatButton(chat)
|
||||
Spacer()
|
||||
AudioCallButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
Spacer()
|
||||
VideoButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
Spacer()
|
||||
} else if groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
if let contactId = member.memberContactId {
|
||||
Spacer()
|
||||
newDirectChatButton(contactId)
|
||||
} else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false {
|
||||
Spacer()
|
||||
createMemberContactButton()
|
||||
}
|
||||
Spacer()
|
||||
InfoViewActionButtonLayout(image: "phone", title: "call", disabledLook: true)
|
||||
InfoViewActionButtonLayout(image: "phone.fill", title: "call", disabledLook: true)
|
||||
.onTapGesture { showSendMessageToEnableCallsAlert() }
|
||||
Spacer()
|
||||
InfoViewActionButtonLayout(image: "video", title: "video", disabledLook: true)
|
||||
InfoViewActionButtonLayout(image: "video.fill", title: "video", disabledLook: true)
|
||||
.onTapGesture { showSendMessageToEnableCallsAlert() }
|
||||
Spacer()
|
||||
} else { // no known contact chat && directMessages are off
|
||||
Spacer()
|
||||
InfoViewActionButtonLayout(image: "message", title: "message", disabledLook: true)
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't message member") }
|
||||
Spacer()
|
||||
InfoViewActionButtonLayout(image: "phone", title: "call", disabledLook: true)
|
||||
InfoViewActionButtonLayout(image: "phone.fill", title: "call", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't call member") }
|
||||
Spacer()
|
||||
InfoViewActionButtonLayout(image: "video", title: "video", disabledLook: true)
|
||||
InfoViewActionButtonLayout(image: "video.fill", title: "video", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't call member") }
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,7 +315,7 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
|
||||
func knownDirectChatButton(_ chat: Chat) -> some View {
|
||||
InfoViewActionButtonLayout(image: "message", title: "message")
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
@@ -335,7 +325,7 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
|
||||
func newDirectChatButton(_ contactId: Int64) -> some View {
|
||||
InfoViewActionButtonLayout(image: "message", title: "message")
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
do {
|
||||
let chat = try apiGetChat(type: .direct, id: contactId)
|
||||
@@ -351,7 +341,7 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
|
||||
func createMemberContactButton() -> some View {
|
||||
InfoViewActionButtonLayout(image: "message", title: "message")
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
progressIndicator = true
|
||||
Task {
|
||||
|
||||
@@ -38,7 +38,6 @@ struct ChatHelp: View {
|
||||
|
||||
HStack(spacing: 8) {
|
||||
Text("Tap button ")
|
||||
// TODO: Check this.
|
||||
NewChatMenuButton()
|
||||
Text("above, then choose:")
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ struct NewChatSheet: View {
|
||||
NavigationView {
|
||||
viewBody()
|
||||
.navigationTitle("New Chat")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.navigationBarHidden(searchMode)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user