mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-27 22:34:51 +00:00
ios: update chat info view (#844)
This commit is contained in:
@@ -310,9 +310,9 @@ final class Chat: ObservableObject, Identifiable {
|
||||
var statusString: LocalizedStringKey {
|
||||
get {
|
||||
switch self {
|
||||
case .connected: return "Server connected"
|
||||
case let .error(err): return "Connecting server… (error: \(err))"
|
||||
default: return "Connecting server…"
|
||||
case .connected: return "connected"
|
||||
case .error: return "error"
|
||||
default: return "connecting"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,69 +9,157 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
func infoRow(_ title: LocalizedStringKey, _ value: String) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
func localizedInfoRow(_ title: LocalizedStringKey, _ value: LocalizedStringKey) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func smpServers(_ title: LocalizedStringKey, _ servers: [String]?) -> some View {
|
||||
if let servers = servers,
|
||||
servers.count > 0 {
|
||||
infoRow(title, serverHost(servers[0]))
|
||||
}
|
||||
}
|
||||
|
||||
private func serverHost(_ s: String) -> String {
|
||||
if let i = s.range(of: "@")?.lowerBound {
|
||||
return String(s[i...].dropFirst())
|
||||
} else {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatInfoView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@ObservedObject var alertManager = AlertManager.shared
|
||||
@ObservedObject var chat: Chat
|
||||
@Binding var showSheet: Bool
|
||||
@State var alert: ChatInfoViewAlert? = nil
|
||||
@State private var alert: ChatInfoViewAlert? = nil
|
||||
@State private var connectionStats: ConnectionStats?
|
||||
|
||||
enum ChatInfoViewAlert: Identifiable {
|
||||
case deleteContactAlert
|
||||
case clearChatAlert
|
||||
case networkStatusAlert
|
||||
|
||||
var id: ChatInfoViewAlert { get { self } }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
ChatInfoImage(chat: chat)
|
||||
.frame(width: 192, height: 192)
|
||||
.padding(.top, 48)
|
||||
.padding()
|
||||
Text(chat.chatInfo.localDisplayName).font(.largeTitle)
|
||||
.padding(.bottom, 2)
|
||||
Text(chat.chatInfo.fullName).font(.title)
|
||||
.padding(.bottom)
|
||||
NavigationView {
|
||||
List {
|
||||
contactInfoHeader()
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
HStack {
|
||||
serverImage()
|
||||
Text(chat.serverInfo.networkStatus.statusString)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
Text(chat.serverInfo.networkStatus.statusExplanation)
|
||||
.font(.subheadline)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.horizontal, 64)
|
||||
.padding(.vertical, 8)
|
||||
if let connStats = connectionStats {
|
||||
Section("Servers") {
|
||||
networkStatusRow()
|
||||
.onTapGesture {
|
||||
alert = .networkStatusAlert
|
||||
}
|
||||
smpServers("Receiving via", connStats.rcvServers)
|
||||
smpServers("Sending via", connStats.sndServers)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
Button() {
|
||||
alert = .clearChatAlert
|
||||
} label: {
|
||||
Label("Clear conversation", systemImage: "gobackward")
|
||||
Section {
|
||||
clearChatButton()
|
||||
deleteContactButton()
|
||||
}
|
||||
|
||||
Section(header: Text("For console")) {
|
||||
infoRow("Local name", chat.chatInfo.localDisplayName)
|
||||
infoRow("Database ID", "\(chat.chatInfo.apiId)")
|
||||
}
|
||||
}
|
||||
.tint(Color.orange)
|
||||
Button(role: .destructive) {
|
||||
alert = .deleteContactAlert
|
||||
} label: {
|
||||
Label("Delete contact", systemImage: "trash")
|
||||
}
|
||||
.padding()
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.alert(item: $alert) { alertItem in
|
||||
switch(alertItem) {
|
||||
case .deleteContactAlert: return deleteContactAlert()
|
||||
case .clearChatAlert: return clearChatAlert()
|
||||
case .networkStatusAlert: return networkStatusAlert()
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.task {
|
||||
do {
|
||||
let stats = try await apiContactInfo(contactId: chat.chatInfo.apiId)
|
||||
await MainActor.run { connectionStats = stats }
|
||||
} catch let error {
|
||||
logger.error("apiContactInfo error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func contactInfoHeader() -> some View {
|
||||
VStack {
|
||||
let cInfo = chat.chatInfo
|
||||
ChatInfoImage(chat: chat, color: Color(uiColor: .tertiarySystemFill))
|
||||
.frame(width: 192, height: 192)
|
||||
.padding(.top, 12)
|
||||
.padding()
|
||||
Text(cInfo.displayName)
|
||||
.font(.largeTitle)
|
||||
.lineLimit(1)
|
||||
.padding(.bottom, 2)
|
||||
if cInfo.fullName != "" && cInfo.fullName != cInfo.displayName {
|
||||
Text(cInfo.fullName)
|
||||
.font(.title2)
|
||||
.lineLimit(2)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
|
||||
func networkStatusRow() -> some View {
|
||||
HStack {
|
||||
Text("Network status")
|
||||
Image(systemName: "info.circle")
|
||||
.foregroundColor(.accentColor)
|
||||
.font(.system(size: 14))
|
||||
Spacer()
|
||||
Text(chat.serverInfo.networkStatus.statusString)
|
||||
.foregroundColor(.secondary)
|
||||
serverImage()
|
||||
}
|
||||
}
|
||||
|
||||
func serverImage() -> some View {
|
||||
let status = chat.serverInfo.networkStatus
|
||||
return Image(systemName: status.imageName)
|
||||
.foregroundColor(status == .connected ? .green : .secondary)
|
||||
.font(.system(size: 12))
|
||||
}
|
||||
|
||||
func deleteContactButton() -> some View {
|
||||
Button(role: .destructive) {
|
||||
alert = .deleteContactAlert
|
||||
} label: {
|
||||
Label("Delete contact", systemImage: "trash")
|
||||
.foregroundColor(Color.red)
|
||||
}
|
||||
}
|
||||
|
||||
func clearChatButton() -> some View {
|
||||
Button() {
|
||||
alert = .clearChatAlert
|
||||
} label: {
|
||||
Label("Clear conversation", systemImage: "gobackward")
|
||||
.foregroundColor(Color.orange)
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteContactAlert() -> Alert {
|
||||
@@ -110,6 +198,13 @@ struct ChatInfoView: View {
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
|
||||
private func networkStatusAlert() -> Alert {
|
||||
Alert(
|
||||
title: Text("Network status"),
|
||||
message: Text(chat.serverInfo.networkStatus.statusExplanation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatInfoView_Previews: PreviewProvider {
|
||||
|
||||
@@ -43,8 +43,8 @@ struct GroupMemberInfoView: View {
|
||||
if let connStats = connectionStats {
|
||||
Section("Servers") {
|
||||
// TODO network connection status
|
||||
smpServers("receiving via", connStats.rcvServers)
|
||||
smpServers("sending via", connStats.sndServers)
|
||||
smpServers("Receiving via", connStats.rcvServers)
|
||||
smpServers("Sending via", connStats.sndServers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,21 +96,6 @@ struct GroupMemberInfoView: View {
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
|
||||
@ViewBuilder private func smpServers(_ title: LocalizedStringKey, _ servers: [String]?) -> some View {
|
||||
if let servers = servers,
|
||||
servers.count > 0 {
|
||||
infoRow(title, serverHost(servers[0]))
|
||||
}
|
||||
}
|
||||
|
||||
private func serverHost(_ s: String) -> String {
|
||||
if let i = s.range(of: "@")?.lowerBound {
|
||||
return String(s[i...].dropFirst())
|
||||
} else {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
func removeMemberButton() -> some View {
|
||||
Button(role: .destructive) {
|
||||
alert = .removeMemberAlert
|
||||
|
||||
@@ -9,24 +9,6 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
func infoRow(_ title: LocalizedStringKey, _ value: String) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
func localizedInfoRow(_ title: LocalizedStringKey, _ value: LocalizedStringKey) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
struct GroupChatInfoView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@ObservedObject var alertManager = AlertManager.shared
|
||||
@@ -174,7 +156,6 @@ struct GroupChatInfoView: View {
|
||||
Label("Clear conversation", systemImage: "gobackward")
|
||||
.foregroundColor(Color.orange)
|
||||
}
|
||||
.tint(Color.orange)
|
||||
}
|
||||
|
||||
func leaveGroupButton() -> some View {
|
||||
|
||||
Reference in New Issue
Block a user