ios: update chat info view (#844)

This commit is contained in:
JRoberts
2022-07-27 13:40:26 +04:00
committed by GitHub
parent aa7e377bce
commit 9864533dae
4 changed files with 134 additions and 73 deletions
+3 -3
View File
@@ -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"
}
}
}
+129 -34
View File
@@ -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 {