core: update event name, ios: types/api/ui (wip) to switch connection to another address, fix contact/member info view, fix setting multiple servers (#1281)
* core: update event name, ios: types/api/ui (wip) to switch connection to another address, fix contact/member info view, fix setting multiple servers * fix * update strings Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
0d0de1da86
commit
d5fc0d7dfc
@@ -357,6 +357,14 @@ func apiGroupMemberInfo(_ groupId: Int64, _ groupMemberId: Int64) async throws -
|
|||||||
throw r
|
throw r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func apiSwitchContact(contactId: Int64) async throws {
|
||||||
|
try await sendCommandOkResp(.apiSwitchContact(contactId: contactId))
|
||||||
|
}
|
||||||
|
|
||||||
|
func apiSwitchGroupMember(_ groupId: Int64, _ groupMemberId: Int64) async throws {
|
||||||
|
try await sendCommandOkResp(.apiSwitchGroupMember(groupId: groupId, groupMemberId: groupMemberId))
|
||||||
|
}
|
||||||
|
|
||||||
func apiAddContact() async -> String? {
|
func apiAddContact() async -> String? {
|
||||||
let r = await chatSendCmd(.addContact, bgTask: false)
|
let r = await chatSendCmd(.addContact, bgTask: false)
|
||||||
if case let .invitation(connReqInvitation) = r { return connReqInvitation }
|
if case let .invitation(connReqInvitation) = r { return connReqInvitation }
|
||||||
|
|||||||
@@ -30,7 +30,14 @@ func localizedInfoRow(_ title: LocalizedStringKey, _ value: LocalizedStringKey)
|
|||||||
@ViewBuilder func smpServers(_ title: LocalizedStringKey, _ servers: [String]?) -> some View {
|
@ViewBuilder func smpServers(_ title: LocalizedStringKey, _ servers: [String]?) -> some View {
|
||||||
if let servers = servers,
|
if let servers = servers,
|
||||||
servers.count > 0 {
|
servers.count > 0 {
|
||||||
infoRow(title, serverHost(servers[0]))
|
HStack {
|
||||||
|
Text(title).frame(width: 120, alignment: .leading)
|
||||||
|
Button(serverHost(servers[0])) {
|
||||||
|
UIPasteboard.general.string = servers.joined(separator: ";")
|
||||||
|
}
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +54,7 @@ struct ChatInfoView: View {
|
|||||||
@Environment(\.dismiss) var dismiss: DismissAction
|
@Environment(\.dismiss) var dismiss: DismissAction
|
||||||
@ObservedObject var chat: Chat
|
@ObservedObject var chat: Chat
|
||||||
var contact: Contact
|
var contact: Contact
|
||||||
var connectionStats: ConnectionStats?
|
@Binding var connectionStats: ConnectionStats?
|
||||||
var customUserProfile: Profile?
|
var customUserProfile: Profile?
|
||||||
@State var localAlias: String
|
@State var localAlias: String
|
||||||
@FocusState private var aliasTextFieldFocused: Bool
|
@FocusState private var aliasTextFieldFocused: Bool
|
||||||
@@ -88,12 +95,15 @@ struct ChatInfoView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let connStats = connectionStats {
|
Section("Servers") {
|
||||||
Section("Servers") {
|
networkStatusRow()
|
||||||
networkStatusRow()
|
.onTapGesture {
|
||||||
.onTapGesture {
|
alert = .networkStatusAlert
|
||||||
alert = .networkStatusAlert
|
}
|
||||||
}
|
Button("Switch receiving address") {
|
||||||
|
|
||||||
|
}
|
||||||
|
if let connStats = connectionStats {
|
||||||
smpServers("Receiving via", connStats.rcvServers)
|
smpServers("Receiving via", connStats.rcvServers)
|
||||||
smpServers("Sending via", connStats.sndServers)
|
smpServers("Sending via", connStats.sndServers)
|
||||||
}
|
}
|
||||||
@@ -258,6 +268,11 @@ struct ChatInfoView: View {
|
|||||||
|
|
||||||
struct ChatInfoView_Previews: PreviewProvider {
|
struct ChatInfoView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ChatInfoView(chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: []), contact: Contact.sampleData, localAlias: "")
|
ChatInfoView(
|
||||||
|
chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: []),
|
||||||
|
contact: Contact.sampleData,
|
||||||
|
connectionStats: Binding.constant(nil),
|
||||||
|
localAlias: ""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// CIGroupEventView.swift
|
// CIEventView.swift
|
||||||
// SimpleX (iOS)
|
// SimpleX (iOS)
|
||||||
//
|
//
|
||||||
// Created by JRoberts on 20.07.2022.
|
// Created by JRoberts on 20.07.2022.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SimpleXChat
|
import SimpleXChat
|
||||||
|
|
||||||
struct CIGroupEventView: View {
|
struct CIEventView: View {
|
||||||
var chatItem: ChatItem
|
var chatItem: ChatItem
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -43,8 +43,8 @@ struct CIGroupEventView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CIGroupEventView_Previews: PreviewProvider {
|
struct CIEventView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
CIGroupEventView(chatItem: ChatItem.getGroupEventSample())
|
CIEventView(chatItem: ChatItem.getGroupEventSample())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,10 @@ struct ChatItemView: View {
|
|||||||
case .rcvIntegrityError: IntegrityErrorItemView(chatItem: chatItem, showMember: showMember)
|
case .rcvIntegrityError: IntegrityErrorItemView(chatItem: chatItem, showMember: showMember)
|
||||||
case let .rcvGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole)
|
case let .rcvGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole)
|
||||||
case let .sndGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole)
|
case let .sndGroupInvitation(groupInvitation, memberRole): groupInvitationItemView(groupInvitation, memberRole)
|
||||||
case .rcvGroupEvent: groupEventItemView()
|
case .rcvGroupEvent: eventItemView()
|
||||||
case .sndGroupEvent: groupEventItemView()
|
case .sndGroupEvent: eventItemView()
|
||||||
|
case .rcvConnEvent: eventItemView()
|
||||||
|
case .sndConnEvent: eventItemView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +54,8 @@ struct ChatItemView: View {
|
|||||||
CIGroupInvitationView(chatItem: chatItem, groupInvitation: groupInvitation, memberRole: memberRole, chatIncognito: chatInfo.incognito)
|
CIGroupInvitationView(chatItem: chatItem, groupInvitation: groupInvitation, memberRole: memberRole, chatIncognito: chatInfo.incognito)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func groupEventItemView() -> some View {
|
private func eventItemView() -> some View {
|
||||||
CIGroupEventView(chatItem: chatItem)
|
CIEventView(chatItem: chatItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ struct ChatView: View {
|
|||||||
connectionStats = nil
|
connectionStats = nil
|
||||||
customUserProfile = nil
|
customUserProfile = nil
|
||||||
}) {
|
}) {
|
||||||
ChatInfoView(chat: chat, contact: contact, connectionStats: connectionStats, customUserProfile: customUserProfile, localAlias: chat.chatInfo.localAlias)
|
ChatInfoView(chat: chat, contact: contact, connectionStats: $connectionStats, customUserProfile: customUserProfile, localAlias: chat.chatInfo.localAlias)
|
||||||
}
|
}
|
||||||
} else if case let .group(groupInfo) = cInfo {
|
} else if case let .group(groupInfo) = cInfo {
|
||||||
Button {
|
Button {
|
||||||
@@ -393,7 +393,7 @@ struct ChatView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sheet(item: $selectedMember, onDismiss: { memberConnectionStats = nil }) { member in
|
.sheet(item: $selectedMember, onDismiss: { memberConnectionStats = nil }) { member in
|
||||||
GroupMemberInfoView(groupInfo: groupInfo, member: member, connectionStats: memberConnectionStats)
|
GroupMemberInfoView(groupInfo: groupInfo, member: member, connectionStats: $memberConnectionStats)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Rectangle().fill(.clear)
|
Rectangle().fill(.clear)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ struct GroupChatInfoView: View {
|
|||||||
AddGroupMembersView(chat: chat, groupInfo: groupInfo)
|
AddGroupMembersView(chat: chat, groupInfo: groupInfo)
|
||||||
}
|
}
|
||||||
.sheet(item: $selectedMember, onDismiss: { connectionStats = nil }) { member in
|
.sheet(item: $selectedMember, onDismiss: { connectionStats = nil }) { member in
|
||||||
GroupMemberInfoView(groupInfo: groupInfo, member: member, connectionStats: connectionStats)
|
GroupMemberInfoView(groupInfo: groupInfo, member: member, connectionStats: $connectionStats)
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $showGroupProfile) {
|
.sheet(isPresented: $showGroupProfile) {
|
||||||
GroupProfileView(groupId: groupInfo.apiId, groupProfile: groupInfo.groupProfile)
|
GroupProfileView(groupId: groupInfo.apiId, groupProfile: groupInfo.groupProfile)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct GroupMemberInfoView: View {
|
|||||||
@Environment(\.dismiss) var dismiss: DismissAction
|
@Environment(\.dismiss) var dismiss: DismissAction
|
||||||
var groupInfo: GroupInfo
|
var groupInfo: GroupInfo
|
||||||
@State var member: GroupMember
|
@State var member: GroupMember
|
||||||
var connectionStats: ConnectionStats?
|
@Binding var connectionStats: ConnectionStats?
|
||||||
@State private var newRole: GroupMemberRole = .member
|
@State private var newRole: GroupMemberRole = .member
|
||||||
@State private var alert: GroupMemberInfoViewAlert?
|
@State private var alert: GroupMemberInfoViewAlert?
|
||||||
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
|
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
|
||||||
@@ -77,9 +77,12 @@ struct GroupMemberInfoView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let connStats = connectionStats {
|
Section("Servers") {
|
||||||
Section("Servers") {
|
// TODO network connection status
|
||||||
// TODO network connection status
|
Button("Switch receiving address") {
|
||||||
|
|
||||||
|
}
|
||||||
|
if let connStats = connectionStats {
|
||||||
smpServers("Receiving via", connStats.rcvServers)
|
smpServers("Receiving via", connStats.rcvServers)
|
||||||
smpServers("Sending via", connStats.sndServers)
|
smpServers("Sending via", connStats.sndServers)
|
||||||
}
|
}
|
||||||
@@ -214,6 +217,10 @@ struct GroupMemberInfoView: View {
|
|||||||
|
|
||||||
struct GroupMemberInfoView_Previews: PreviewProvider {
|
struct GroupMemberInfoView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
GroupMemberInfoView(groupInfo: GroupInfo.sampleData, member: GroupMember.sampleData)
|
GroupMemberInfoView(
|
||||||
|
groupInfo: GroupInfo.sampleData,
|
||||||
|
member: GroupMember.sampleData,
|
||||||
|
connectionStats: Binding.constant(nil)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
64328561290BEE2B00FBE5C8 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855C290BEE2B00FBE5C8 /* libgmpxx.a */; };
|
64328561290BEE2B00FBE5C8 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855C290BEE2B00FBE5C8 /* libgmpxx.a */; };
|
||||||
64328562290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */; };
|
64328562290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */; };
|
||||||
64328563290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */; };
|
64328563290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */; };
|
||||||
6440CA00288857A10062C672 /* CIGroupEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440C9FF288857A10062C672 /* CIGroupEventView.swift */; };
|
6440CA00288857A10062C672 /* CIEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440C9FF288857A10062C672 /* CIEventView.swift */; };
|
||||||
6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */; };
|
6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440CA02288AECA70062C672 /* AddGroupMembersView.swift */; };
|
||||||
6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */; };
|
6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0B9287F169300CEC0F9 /* AddGroupView.swift */; };
|
||||||
6442E0BE2880182D00CEC0F9 /* GroupChatInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */; };
|
6442E0BE2880182D00CEC0F9 /* GroupChatInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */; };
|
||||||
@@ -324,7 +324,7 @@
|
|||||||
6432855C290BEE2B00FBE5C8 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
6432855C290BEE2B00FBE5C8 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||||
6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a"; sourceTree = "<group>"; };
|
6432855D290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu-ghc8.10.7.a"; sourceTree = "<group>"; };
|
||||||
6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a"; sourceTree = "<group>"; };
|
6432855E290BEE2B00FBE5C8 /* libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.2.0-LeYwSLlznBGLTzzJTly7Iu.a"; sourceTree = "<group>"; };
|
||||||
6440C9FF288857A10062C672 /* CIGroupEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupEventView.swift; sourceTree = "<group>"; };
|
6440C9FF288857A10062C672 /* CIEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIEventView.swift; sourceTree = "<group>"; };
|
||||||
6440CA02288AECA70062C672 /* AddGroupMembersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersView.swift; sourceTree = "<group>"; };
|
6440CA02288AECA70062C672 /* AddGroupMembersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersView.swift; sourceTree = "<group>"; };
|
||||||
6442E0B9287F169300CEC0F9 /* AddGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupView.swift; sourceTree = "<group>"; };
|
6442E0B9287F169300CEC0F9 /* AddGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupView.swift; sourceTree = "<group>"; };
|
||||||
6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatInfoView.swift; sourceTree = "<group>"; };
|
6442E0BD2880182D00CEC0F9 /* GroupChatInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatInfoView.swift; sourceTree = "<group>"; };
|
||||||
@@ -647,7 +647,7 @@
|
|||||||
5C029EA72837DBB3004A9677 /* CICallItemView.swift */,
|
5C029EA72837DBB3004A9677 /* CICallItemView.swift */,
|
||||||
5C3F1D552842B68D00EC8A82 /* IntegrityErrorItemView.swift */,
|
5C3F1D552842B68D00EC8A82 /* IntegrityErrorItemView.swift */,
|
||||||
64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */,
|
64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */,
|
||||||
6440C9FF288857A10062C672 /* CIGroupEventView.swift */,
|
6440C9FF288857A10062C672 /* CIEventView.swift */,
|
||||||
);
|
);
|
||||||
path = ChatItem;
|
path = ChatItem;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -966,7 +966,7 @@
|
|||||||
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */,
|
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */,
|
||||||
5CB924D427A853F100ACCCDD /* SettingsButton.swift in Sources */,
|
5CB924D427A853F100ACCCDD /* SettingsButton.swift in Sources */,
|
||||||
3C714777281C081000CB4D4B /* WebRTCView.swift in Sources */,
|
3C714777281C081000CB4D4B /* WebRTCView.swift in Sources */,
|
||||||
6440CA00288857A10062C672 /* CIGroupEventView.swift in Sources */,
|
6440CA00288857A10062C672 /* CIEventView.swift in Sources */,
|
||||||
5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */,
|
5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */,
|
||||||
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */,
|
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */,
|
||||||
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */,
|
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */,
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public enum ChatCommand {
|
|||||||
case apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings)
|
case apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings)
|
||||||
case apiContactInfo(contactId: Int64)
|
case apiContactInfo(contactId: Int64)
|
||||||
case apiGroupMemberInfo(groupId: Int64, groupMemberId: Int64)
|
case apiGroupMemberInfo(groupId: Int64, groupMemberId: Int64)
|
||||||
|
case apiSwitchContact(contactId: Int64)
|
||||||
|
case apiSwitchGroupMember(groupId: Int64, groupMemberId: Int64)
|
||||||
case addContact
|
case addContact
|
||||||
case connect(connReq: String)
|
case connect(connReq: String)
|
||||||
case apiDeleteChat(type: ChatType, id: Int64)
|
case apiDeleteChat(type: ChatType, id: Int64)
|
||||||
@@ -131,6 +133,8 @@ public enum ChatCommand {
|
|||||||
case let .apiSetChatSettings(type, id, chatSettings): return "/_settings \(ref(type, id)) \(encodeJSON(chatSettings))"
|
case let .apiSetChatSettings(type, id, chatSettings): return "/_settings \(ref(type, id)) \(encodeJSON(chatSettings))"
|
||||||
case let .apiContactInfo(contactId): return "/_info @\(contactId)"
|
case let .apiContactInfo(contactId): return "/_info @\(contactId)"
|
||||||
case let .apiGroupMemberInfo(groupId, groupMemberId): return "/_info #\(groupId) \(groupMemberId)"
|
case let .apiGroupMemberInfo(groupId, groupMemberId): return "/_info #\(groupId) \(groupMemberId)"
|
||||||
|
case let .apiSwitchContact(contactId): return "/_switch @\(contactId)"
|
||||||
|
case let .apiSwitchGroupMember(groupId, groupMemberId): return "/_switch #\(groupId) \(groupMemberId)"
|
||||||
case .addContact: return "/connect"
|
case .addContact: return "/connect"
|
||||||
case let .connect(connReq): return "/connect \(connReq)"
|
case let .connect(connReq): return "/connect \(connReq)"
|
||||||
case let .apiDeleteChat(type, id): return "/_delete \(ref(type, id))"
|
case let .apiDeleteChat(type, id): return "/_delete \(ref(type, id))"
|
||||||
@@ -206,6 +210,8 @@ public enum ChatCommand {
|
|||||||
case .apiSetChatSettings: return "apiSetChatSettings"
|
case .apiSetChatSettings: return "apiSetChatSettings"
|
||||||
case .apiContactInfo: return "apiContactInfo"
|
case .apiContactInfo: return "apiContactInfo"
|
||||||
case .apiGroupMemberInfo: return "apiGroupMemberInfo"
|
case .apiGroupMemberInfo: return "apiGroupMemberInfo"
|
||||||
|
case .apiSwitchContact: return "apiSwitchContact"
|
||||||
|
case .apiSwitchGroupMember: return "apiSwitchGroupMember"
|
||||||
case .addContact: return "addContact"
|
case .addContact: return "addContact"
|
||||||
case .connect: return "connect"
|
case .connect: return "connect"
|
||||||
case .apiDeleteChat: return "apiDeleteChat"
|
case .apiDeleteChat: return "apiDeleteChat"
|
||||||
@@ -241,7 +247,7 @@ public enum ChatCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func smpServersStr(smpServers: [String]) -> String {
|
func smpServersStr(smpServers: [String]) -> String {
|
||||||
smpServers.isEmpty ? "default" : smpServers.joined(separator: ",")
|
smpServers.isEmpty ? "default" : smpServers.joined(separator: ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
func chatItemTTLStr(seconds: Int64?) -> String {
|
func chatItemTTLStr(seconds: Int64?) -> String {
|
||||||
|
|||||||
@@ -711,6 +711,11 @@ public struct GroupMember: Identifiable, Decodable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct GroupMemberRef: Decodable {
|
||||||
|
var groupMemberId: Int64
|
||||||
|
var profile: Profile
|
||||||
|
}
|
||||||
|
|
||||||
public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Decodable {
|
public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Decodable {
|
||||||
case member = "member"
|
case member = "member"
|
||||||
case admin = "admin"
|
case admin = "admin"
|
||||||
@@ -1096,6 +1101,8 @@ public enum CIContent: Decodable, ItemContent {
|
|||||||
case sndGroupInvitation(groupInvitation: CIGroupInvitation, memberRole: GroupMemberRole)
|
case sndGroupInvitation(groupInvitation: CIGroupInvitation, memberRole: GroupMemberRole)
|
||||||
case rcvGroupEvent(rcvGroupEvent: RcvGroupEvent)
|
case rcvGroupEvent(rcvGroupEvent: RcvGroupEvent)
|
||||||
case sndGroupEvent(sndGroupEvent: SndGroupEvent)
|
case sndGroupEvent(sndGroupEvent: SndGroupEvent)
|
||||||
|
case rcvConnEvent(rcvConnEvent: RcvConnEvent)
|
||||||
|
case sndConnEvent(sndConnEvent: SndConnEvent)
|
||||||
|
|
||||||
public var text: String {
|
public var text: String {
|
||||||
get {
|
get {
|
||||||
@@ -1111,6 +1118,8 @@ public enum CIContent: Decodable, ItemContent {
|
|||||||
case let .sndGroupInvitation(groupInvitation, _): return groupInvitation.text
|
case let .sndGroupInvitation(groupInvitation, _): return groupInvitation.text
|
||||||
case let .rcvGroupEvent(rcvGroupEvent): return rcvGroupEvent.text
|
case let .rcvGroupEvent(rcvGroupEvent): return rcvGroupEvent.text
|
||||||
case let .sndGroupEvent(sndGroupEvent): return sndGroupEvent.text
|
case let .sndGroupEvent(sndGroupEvent): return sndGroupEvent.text
|
||||||
|
case let .rcvConnEvent(rcvConnEvent): return rcvConnEvent.text
|
||||||
|
case let .sndConnEvent(sndConnEvent): return sndConnEvent.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1498,6 +1507,44 @@ public enum SndGroupEvent: Decodable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum RcvConnEvent: Decodable {
|
||||||
|
case switchQueue(phase: SwitchPhase)
|
||||||
|
|
||||||
|
var text: String {
|
||||||
|
switch self {
|
||||||
|
case let .switchQueue(phase):
|
||||||
|
if case .completed = phase {
|
||||||
|
return NSLocalizedString("changed address for you", comment: "chat item text")
|
||||||
|
}
|
||||||
|
return NSLocalizedString("changing address...", comment: "chat item text")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SndConnEvent: Decodable {
|
||||||
|
case switchQueue(phase: SwitchPhase, member: GroupMemberRef?)
|
||||||
|
|
||||||
|
var text: String {
|
||||||
|
switch self {
|
||||||
|
case let .switchQueue(phase, member):
|
||||||
|
if let name = member?.profile.profileViewName {
|
||||||
|
return phase == .completed
|
||||||
|
? String.localizedStringWithFormat(NSLocalizedString("you changed address for %@", comment: "chat item text"), name)
|
||||||
|
: String.localizedStringWithFormat(NSLocalizedString("changing address for %@...", comment: "chat item text"), name)
|
||||||
|
}
|
||||||
|
return phase == .completed
|
||||||
|
? NSLocalizedString("you changed address", comment: "chat item text")
|
||||||
|
: NSLocalizedString("changing address...", comment: "chat item text")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SwitchPhase: String, Decodable {
|
||||||
|
case started
|
||||||
|
case confirmed
|
||||||
|
case completed
|
||||||
|
}
|
||||||
|
|
||||||
public enum ChatItemTTL: Hashable, Identifiable, Comparable {
|
public enum ChatItemTTL: Hashable, Identifiable, Comparable {
|
||||||
case day
|
case day
|
||||||
case week
|
case week
|
||||||
|
|||||||
@@ -1760,8 +1760,8 @@ processAgentMessage (Just user@User {userId}) corrId agentConnId agentMessage =
|
|||||||
SWITCH qd phase cStats -> do
|
SWITCH qd phase cStats -> do
|
||||||
toView . CRContactSwitch ct $ SwitchProgress qd phase cStats
|
toView . CRContactSwitch ct $ SwitchProgress qd phase cStats
|
||||||
when (phase /= SPConfirmed) $ case qd of
|
when (phase /= SPConfirmed) $ case qd of
|
||||||
QDRcv -> createInternalChatItem (CDDirectSnd ct) (CISndConnEvent $ SCESwitch phase Nothing) Nothing
|
QDRcv -> createInternalChatItem (CDDirectSnd ct) (CISndConnEvent $ SCESwitchQueue phase Nothing) Nothing
|
||||||
QDSnd -> createInternalChatItem (CDDirectRcv ct) (CIRcvConnEvent $ RCESwitch phase) Nothing
|
QDSnd -> createInternalChatItem (CDDirectRcv ct) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
||||||
OK ->
|
OK ->
|
||||||
-- [async agent commands] continuation on receiving OK
|
-- [async agent commands] continuation on receiving OK
|
||||||
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} ->
|
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} ->
|
||||||
@@ -1907,8 +1907,8 @@ processAgentMessage (Just user@User {userId}) corrId agentConnId agentMessage =
|
|||||||
SWITCH qd phase cStats -> do
|
SWITCH qd phase cStats -> do
|
||||||
toView . CRGroupMemberSwitch gInfo m $ SwitchProgress qd phase cStats
|
toView . CRGroupMemberSwitch gInfo m $ SwitchProgress qd phase cStats
|
||||||
when (phase /= SPConfirmed) $ case qd of
|
when (phase /= SPConfirmed) $ case qd of
|
||||||
QDRcv -> createInternalChatItem (CDGroupSnd gInfo) (CISndConnEvent . SCESwitch phase . Just $ groupMemberRef m) Nothing
|
QDRcv -> createInternalChatItem (CDGroupSnd gInfo) (CISndConnEvent . SCESwitchQueue phase . Just $ groupMemberRef m) Nothing
|
||||||
QDSnd -> createInternalChatItem (CDGroupRcv gInfo m) (CIRcvConnEvent $ RCESwitch phase) Nothing
|
QDSnd -> createInternalChatItem (CDGroupRcv gInfo m) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
||||||
OK ->
|
OK ->
|
||||||
-- [async agent commands] continuation on receiving OK
|
-- [async agent commands] continuation on receiving OK
|
||||||
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} ->
|
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} ->
|
||||||
|
|||||||
@@ -525,13 +525,13 @@ sndGroupEventToText = \case
|
|||||||
|
|
||||||
rcvConnEventToText :: RcvConnEvent -> Text
|
rcvConnEventToText :: RcvConnEvent -> Text
|
||||||
rcvConnEventToText = \case
|
rcvConnEventToText = \case
|
||||||
RCESwitch phase -> case phase of
|
RCESwitchQueue phase -> case phase of
|
||||||
SPCompleted -> "changed address for you"
|
SPCompleted -> "changed address for you"
|
||||||
_ -> decodeLatin1 (strEncode phase) <> " changing address for you..."
|
_ -> decodeLatin1 (strEncode phase) <> " changing address for you..."
|
||||||
|
|
||||||
sndConnEventToText :: SndConnEvent -> Text
|
sndConnEventToText :: SndConnEvent -> Text
|
||||||
sndConnEventToText = \case
|
sndConnEventToText = \case
|
||||||
SCESwitch phase m -> case phase of
|
SCESwitchQueue phase m -> case phase of
|
||||||
SPCompleted -> "you changed address" <> forMember m
|
SPCompleted -> "you changed address" <> forMember m
|
||||||
_ -> decodeLatin1 (strEncode phase) <> " changing address" <> forMember m <> "..."
|
_ -> decodeLatin1 (strEncode phase) <> " changing address" <> forMember m <> "..."
|
||||||
where
|
where
|
||||||
@@ -620,10 +620,10 @@ instance ToJSON DBSndGroupEvent where
|
|||||||
toJSON (SGE v) = J.genericToJSON (singleFieldJSON $ dropPrefix "SGE") v
|
toJSON (SGE v) = J.genericToJSON (singleFieldJSON $ dropPrefix "SGE") v
|
||||||
toEncoding (SGE v) = J.genericToEncoding (singleFieldJSON $ dropPrefix "SGE") v
|
toEncoding (SGE v) = J.genericToEncoding (singleFieldJSON $ dropPrefix "SGE") v
|
||||||
|
|
||||||
data RcvConnEvent = RCESwitch {phase :: SwitchPhase}
|
data RcvConnEvent = RCESwitchQueue {phase :: SwitchPhase}
|
||||||
deriving (Show, Generic)
|
deriving (Show, Generic)
|
||||||
|
|
||||||
data SndConnEvent = SCESwitch {phase :: SwitchPhase, member :: Maybe GroupMemberRef}
|
data SndConnEvent = SCESwitchQueue {phase :: SwitchPhase, member :: Maybe GroupMemberRef}
|
||||||
deriving (Show, Generic)
|
deriving (Show, Generic)
|
||||||
|
|
||||||
instance FromJSON RcvConnEvent where
|
instance FromJSON RcvConnEvent where
|
||||||
|
|||||||
Reference in New Issue
Block a user