reconnect server button

This commit is contained in:
spaced4ndy
2024-06-26 10:58:26 +04:00
parent 4f2838d329
commit fd11c9d0b3
3 changed files with 128 additions and 70 deletions
+5
View File
@@ -541,6 +541,11 @@ func reconnectAllServers() async throws {
try await sendCommandOkResp(.reconnectAllServers)
}
func reconnectServer(smpServer: String) async throws {
let userId = try currentUserId("reconnectServer")
try await sendCommandOkResp(.reconnectServer(userId: userId, smpServer: smpServer))
}
func apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings) async throws {
try await sendCommandOkResp(.apiSetChatSettings(type: type, id: id, chatSettings: chatSettings))
}
@@ -329,6 +329,7 @@ struct SMPServerSummaryView: View {
var summary: SMPServerSummary
var showReconnectButton: Bool
var statsStartedAt: Date
@State private var alert: SomeAlert?
var body: some View {
List {
@@ -346,63 +347,101 @@ struct SMPServerSummaryView: View {
Text("Server address")
} footer: {
if let known = summary.known, known {
// TODO open settings?
Text("Server is configured in **Settings** → **Network & servers** → **SMP servers**.")
Text("Server is configured in **Settings** → **Network & servers**.")
}
}
if showReconnectButton {
Section {
Button {
// TODO
} label: {
Text("TODO Reconnect")
}
}
}
if let sess = summary.sessions {
Section("Sessions") {
infoRow("Connected", "\(sess.ssConnected)")
infoRow("Errors", "\(sess.ssErrors)")
infoRow("Connecting", "\(sess.ssConnecting)")
}
reconnectButtonSection()
}
if let subs = summary.subs {
Section("Subscriptions") {
infoRow("Active", "\(subs.ssActive)")
infoRow("Pending", "\(subs.ssPending)")
}
subsSection(subs)
}
if let sess = summary.sessions {
sessionsSection(sess)
}
if let stats = summary.stats {
Section("Statistics") {
infoRow("Messages sent directly", "\(stats._sentDirect)")
infoRow(" attempts", "\(stats._sentDirectAttempts)")
infoRow("Messages sent via proxy", "\(stats._sentViaProxy)")
infoRow(" attempts", "\(stats._sentViaProxyAttempts)")
infoRow("Messages sent to proxy", "\(stats._sentProxied)")
infoRow(" attempts", "\(stats._sentProxiedAttempts)")
infoRow("Send AUTH errors", "\(stats._sentAuthErrs)")
infoRow(" QUOTA errors", "\(stats._sentQuotaErrs)")
infoRow(" expired", "\(stats._sentExpiredErrs)")
infoRow(" other errors", "\(stats._sentOtherErrs)")
infoRow("Messages received", "\(stats._recvMsgs)")
infoRow(" duplicates", "\(stats._recvDuplicates)")
infoRow(" decryption", "\(stats._recvCryptoErrs)")
infoRow(" other errors", "\(stats._recvErrs)")
infoRow("Connections created", "\(stats._connCreated)")
infoRow(" secured", "\(stats._connSecured)")
infoRow(" completed", "\(stats._connCompleted)")
infoRow("Connections deleted", "\(stats._connDeleted)")
infoRow("Connections subscribed", "\(stats._connSubscribed)")
infoRow(" attempts", "\(stats._connSubAttempts)")
infoRow(" errors", "\(stats._connSubErrs)")
infoRow("From", localTimestamp(statsStartedAt))
}
statsSection(stats)
}
}
.alert(item: $alert) { $0.alert }
}
private func reconnectButtonSection() -> some View {
Section {
Button {
alert = SomeAlert(
alert: Alert(
title: Text("Reconnect server?"),
message: Text("Reconnect server to force message delivery. It uses additional traffic."),
primaryButton: .default(Text("Ok")) {
Task {
do {
try await reconnectServer(smpServer: summary.smpServer)
} catch let error {
alert = SomeAlert(
alert: mkAlert(
title: "Error reconnecting server",
message: "\(responseError(error))"
),
id: "error reconnecting server"
)
}
}
},
secondaryButton: .cancel()
),
id: "reconnect server question"
)
} label: {
Text("Reconnect")
}
}
}
private func subsSection(_ subs: SMPServerSubs) -> some View {
Section("Subscriptions") {
infoRow("Active", "\(subs.ssActive)")
infoRow("Pending", "\(subs.ssPending)")
}
}
private func sessionsSection(_ sess: ServerSessions) -> some View {
Section("Sessions") {
infoRow("Connected", "\(sess.ssConnected)")
infoRow("Errors", "\(sess.ssErrors)")
infoRow("Connecting", "\(sess.ssConnecting)")
}
}
private func statsSection(_ stats: AgentSMPServerStatsData) -> some View {
Section("Statistics") {
infoRow("Starting from", localTimestamp(statsStartedAt))
infoRow("Messages sent directly", "\(stats._sentDirect)")
infoRow(" attempts", "\(stats._sentDirectAttempts)")
infoRow("Messages sent via proxy", "\(stats._sentViaProxy)")
infoRow(" attempts", "\(stats._sentViaProxyAttempts)")
infoRow("Messages sent to proxy", "\(stats._sentProxied)")
infoRow(" attempts", "\(stats._sentProxiedAttempts)")
infoRow("Send AUTH errors", "\(stats._sentAuthErrs)")
infoRow(" QUOTA errors", "\(stats._sentQuotaErrs)")
infoRow(" expired", "\(stats._sentExpiredErrs)")
infoRow(" other errors", "\(stats._sentOtherErrs)")
infoRow("Messages received", "\(stats._recvMsgs)")
infoRow(" duplicates", "\(stats._recvDuplicates)")
infoRow(" decryption", "\(stats._recvCryptoErrs)")
infoRow(" other errors", "\(stats._recvErrs)")
infoRow("Connections created", "\(stats._connCreated)")
infoRow(" secured", "\(stats._connSecured)")
infoRow(" completed", "\(stats._connCompleted)")
infoRow("Connections deleted", "\(stats._connDeleted)")
infoRow("Connections subscribed", "\(stats._connSubscribed)")
infoRow(" attempts", "\(stats._connSubAttempts)")
infoRow(" errors", "\(stats._connSubErrs)")
}
}
}
@@ -426,46 +465,57 @@ struct XFTPServerSummaryView: View {
Text("Server address")
} footer: {
if let known = summary.known, known {
// TODO open settings?
Text("Server can be configured in **Settings** → **Network & servers** → **XFTP servers**")
Text("Server is configured in **Settings** → **Network & servers**.")
}
}
if let sess = summary.sessions {
Section("Sessions") {
infoRow("Connected", "\(sess.ssConnected)")
infoRow("Errors", "\(sess.ssErrors)")
infoRow("Connecting", "\(sess.ssConnecting)")
}
sessionsSection(sess)
}
Section("In progress") {
localizedInfoRow("Download", boolYesNo(summary.rcvInProgress))
localizedInfoRow("Upload", boolYesNo(summary.sndInProgress))
localizedInfoRow("Deletion", boolYesNo(summary.delInProgress))
}
inProgressSection()
if let stats = summary.stats {
Section("Statistics") {
infoRow("Chunks uploaded", "\(stats._uploads)")
infoRow(" attempts", "\(stats._uploadAttempts)")
infoRow(" errors", "\(stats._uploadErrs)")
infoRow("Chunks downloaded", "\(stats._downloads)")
infoRow(" attempts", "\(stats._downloadAttempts)")
infoRow(" AUTH errors", "\(stats._downloadAuthErrs)")
infoRow(" other errors", "\(stats._downloadErrs)")
infoRow("Chunks deleted", "\(stats._deletions)")
infoRow(" attempts", "\(stats._deleteAttempts)")
infoRow(" errors", "\(stats._deleteErrs)")
infoRow("From", localTimestamp(statsStartedAt))
}
statsSection(stats)
}
}
}
private func sessionsSection(_ sess: ServerSessions) -> some View {
Section("Sessions") {
infoRow("Connected", "\(sess.ssConnected)")
infoRow("Errors", "\(sess.ssErrors)")
infoRow("Connecting", "\(sess.ssConnecting)")
}
}
private func inProgressSection() -> some View {
Section("In progress") {
localizedInfoRow("Download", boolYesNo(summary.rcvInProgress))
localizedInfoRow("Upload", boolYesNo(summary.sndInProgress))
localizedInfoRow("Deletion", boolYesNo(summary.delInProgress))
}
}
private func boolYesNo(_ b: Bool) -> LocalizedStringKey {
b ? "yes" : "no"
}
private func statsSection(_ stats: AgentXFTPServerStatsData) -> some View {
Section("Statistics") {
infoRow("Starting from", localTimestamp(statsStartedAt))
infoRow("Chunks uploaded", "\(stats._uploads)")
infoRow(" attempts", "\(stats._uploadAttempts)")
infoRow(" errors", "\(stats._uploadErrs)")
infoRow("Chunks downloaded", "\(stats._downloads)")
infoRow(" attempts", "\(stats._downloadAttempts)")
infoRow(" AUTH errors", "\(stats._downloadAuthErrs)")
infoRow(" other errors", "\(stats._downloadErrs)")
infoRow("Chunks deleted", "\(stats._deletions)")
infoRow(" attempts", "\(stats._deleteAttempts)")
infoRow(" errors", "\(stats._deleteErrs)")
}
}
}
#Preview {
+3
View File
@@ -78,6 +78,7 @@ public enum ChatCommand {
case apiGetNetworkConfig
case apiSetNetworkInfo(networkInfo: UserNetworkInfo)
case reconnectAllServers
case reconnectServer(userId: Int64, smpServer: String)
case apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings)
case apiSetMemberSettings(groupId: Int64, groupMemberId: Int64, memberSettings: GroupMemberSettings)
case apiContactInfo(contactId: Int64)
@@ -228,6 +229,7 @@ public enum ChatCommand {
case .apiGetNetworkConfig: return "/network"
case let .apiSetNetworkInfo(networkInfo): return "/_network info \(encodeJSON(networkInfo))"
case .reconnectAllServers: return "/reconnect"
case let .reconnectServer(userId, smpServer): return "/reconnect \(userId) \(smpServer)"
case let .apiSetChatSettings(type, id, chatSettings): return "/_settings \(ref(type, id)) \(encodeJSON(chatSettings))"
case let .apiSetMemberSettings(groupId, groupMemberId, memberSettings): return "/_member settings #\(groupId) \(groupMemberId) \(encodeJSON(memberSettings))"
case let .apiContactInfo(contactId): return "/_info @\(contactId)"
@@ -378,6 +380,7 @@ public enum ChatCommand {
case .apiGetNetworkConfig: return "apiGetNetworkConfig"
case .apiSetNetworkInfo: return "apiSetNetworkInfo"
case .reconnectAllServers: return "reconnectAllServers"
case .reconnectServer: return "reconnectServer"
case .apiSetChatSettings: return "apiSetChatSettings"
case .apiSetMemberSettings: return "apiSetMemberSettings"
case .apiContactInfo: return "apiContactInfo"