mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-04-27 06:25:48 +00:00
Merge branch 'master' into directory-service
This commit is contained in:
@@ -802,33 +802,41 @@ func apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool) async throws {
|
||||
try await sendCommandOkResp(.apiChatUnread(type: type, id: id, unreadChat: unreadChat))
|
||||
}
|
||||
|
||||
func receiveFile(user: User, fileId: Int64) async {
|
||||
if let chatItem = await apiReceiveFile(fileId: fileId) {
|
||||
func receiveFile(user: User, fileId: Int64, auto: Bool = false) async {
|
||||
if let chatItem = await apiReceiveFile(fileId: fileId, auto: auto) {
|
||||
DispatchQueue.main.async { chatItemSimpleUpdate(user, chatItem) }
|
||||
}
|
||||
}
|
||||
|
||||
func apiReceiveFile(fileId: Int64, inline: Bool? = nil) async -> AChatItem? {
|
||||
func apiReceiveFile(fileId: Int64, inline: Bool? = nil, auto: Bool = false) async -> AChatItem? {
|
||||
let r = await chatSendCmd(.receiveFile(fileId: fileId, inline: inline))
|
||||
let am = AlertManager.shared
|
||||
if case let .rcvFileAccepted(_, chatItem) = r { return chatItem }
|
||||
if case .rcvFileAcceptedSndCancelled = r {
|
||||
am.showAlertMsg(
|
||||
title: "Cannot receive file",
|
||||
message: "Sender cancelled file transfer."
|
||||
)
|
||||
logger.debug("apiReceiveFile error: sender cancelled file transfer")
|
||||
if !auto {
|
||||
am.showAlertMsg(
|
||||
title: "Cannot receive file",
|
||||
message: "Sender cancelled file transfer."
|
||||
)
|
||||
}
|
||||
} else if let networkErrorAlert = networkErrorAlert(r) {
|
||||
am.showAlert(networkErrorAlert)
|
||||
logger.error("apiReceiveFile network error: \(String(describing: r))")
|
||||
if !auto {
|
||||
am.showAlert(networkErrorAlert)
|
||||
}
|
||||
} else {
|
||||
logger.error("apiReceiveFile error: \(String(describing: r))")
|
||||
switch r {
|
||||
case .chatCmdError(_, .error(.fileAlreadyReceiving)):
|
||||
logger.debug("apiReceiveFile ignoring fileAlreadyReceiving error")
|
||||
default:
|
||||
am.showAlertMsg(
|
||||
title: "Error receiving file",
|
||||
message: "Error: \(String(describing: r))"
|
||||
)
|
||||
logger.error("apiReceiveFile error: \(String(describing: r))")
|
||||
if !auto {
|
||||
am.showAlertMsg(
|
||||
title: "Error receiving file",
|
||||
message: "Error: \(String(describing: r))"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1323,7 +1331,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
}
|
||||
if let file = cItem.autoReceiveFile() {
|
||||
Task {
|
||||
await receiveFile(user: user, fileId: file.fileId)
|
||||
await receiveFile(user: user, fileId: file.fileId, auto: true)
|
||||
}
|
||||
}
|
||||
if cItem.showNotification {
|
||||
|
||||
@@ -247,10 +247,10 @@ struct CIVideoView: View {
|
||||
.padding([.trailing, .top], 11)
|
||||
}
|
||||
|
||||
private func receiveFileIfValidSize(file: CIFile, receiveFile: @escaping (User, Int64) async -> Void) {
|
||||
private func receiveFileIfValidSize(file: CIFile, receiveFile: @escaping (User, Int64, Bool) async -> Void) {
|
||||
Task {
|
||||
if let user = ChatModel.shared.currentUser {
|
||||
await receiveFile(user, file.fileId)
|
||||
await receiveFile(user, file.fileId, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ struct MsgContentView: View {
|
||||
func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: String?, icon: String? = nil, preview: Bool = false) -> Text {
|
||||
let s = text
|
||||
var res: Text
|
||||
if let ft = formattedText, ft.count > 0 {
|
||||
if let ft = formattedText, ft.count > 0 && ft.count <= 200 {
|
||||
res = formatText(ft[0], preview)
|
||||
var i = 1
|
||||
while i < ft.count {
|
||||
|
||||
@@ -28,6 +28,7 @@ struct GroupMemberInfoView: View {
|
||||
case switchAddressAlert
|
||||
case abortSwitchAddressAlert
|
||||
case syncConnectionForceAlert
|
||||
case connectViaMemberAddressAlert(contactLink: String)
|
||||
case connRequestSentAlert(type: ConnReqType)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey)
|
||||
case other(alert: Alert)
|
||||
@@ -38,8 +39,9 @@ struct GroupMemberInfoView: View {
|
||||
case let .changeMemberRoleAlert(_, role): return "changeMemberRoleAlert \(role.rawValue)"
|
||||
case .switchAddressAlert: return "switchAddressAlert"
|
||||
case .abortSwitchAddressAlert: return "abortSwitchAddressAlert"
|
||||
case .connRequestSentAlert: return "connRequestSentAlert"
|
||||
case .syncConnectionForceAlert: return "syncConnectionForceAlert"
|
||||
case .connectViaMemberAddressAlert: return "connectViaMemberAddressAlert"
|
||||
case .connRequestSentAlert: return "connRequestSentAlert"
|
||||
case let .error(title, _): return "error \(title)"
|
||||
case let .other(alert): return "other \(alert)"
|
||||
}
|
||||
@@ -201,6 +203,7 @@ struct GroupMemberInfoView: View {
|
||||
case .switchAddressAlert: return switchAddressAlert(switchMemberAddress)
|
||||
case .abortSwitchAddressAlert: return abortSwitchAddressAlert(abortSwitchMemberAddress)
|
||||
case .syncConnectionForceAlert: return syncConnectionForceAlert({ syncMemberConnection(force: true) })
|
||||
case let .connectViaMemberAddressAlert(contactLink): return connectViaMemberAddressAlert(contactLink)
|
||||
case let .connRequestSentAlert(type): return connReqSentAlert(type)
|
||||
case let .error(title, error): return Alert(title: Text(title), message: Text(error))
|
||||
case let .other(alert): return alert
|
||||
@@ -210,12 +213,23 @@ struct GroupMemberInfoView: View {
|
||||
|
||||
func connectViaAddressButton(_ contactLink: String) -> some View {
|
||||
Button {
|
||||
connectViaAddress(contactLink)
|
||||
alert = .connectViaMemberAddressAlert(contactLink: contactLink)
|
||||
} label: {
|
||||
Label("Connect", systemImage: "link")
|
||||
}
|
||||
}
|
||||
|
||||
func connectViaMemberAddressAlert(_ contactLink: String) -> Alert {
|
||||
return Alert(
|
||||
title: Text("Connect directly?"),
|
||||
message: Text("Сonnection request will be sent to this group member."),
|
||||
primaryButton: .default(Text("Connect")) {
|
||||
connectViaAddress(contactLink)
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
|
||||
func connectViaAddress(_ contactLink: String) {
|
||||
Task {
|
||||
let (connReqType, connectAlert) = await apiConnect_(connReq: contactLink)
|
||||
|
||||
@@ -206,7 +206,7 @@ public func responseError(_ err: Error) -> String {
|
||||
switch r {
|
||||
case let .chatCmdError(_, chatError): return chatErrorString(chatError)
|
||||
case let .chatError(_, chatError): return chatErrorString(chatError)
|
||||
default: return String(describing: r)
|
||||
default: return "\(String(describing: r.responseType)), details: \(String(describing: r.details))"
|
||||
}
|
||||
} else {
|
||||
return String(describing: err)
|
||||
|
||||
@@ -452,6 +452,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case sentConfirmation(user: User)
|
||||
case sentInvitation(user: User)
|
||||
case contactAlreadyExists(user: User, contact: Contact)
|
||||
case contactRequestAlreadyAccepted(user: User, contact: Contact)
|
||||
case contactDeleted(user: User, contact: Contact)
|
||||
case chatCleared(user: User, chatInfo: ChatInfo)
|
||||
case userProfileNoChange(user: User)
|
||||
@@ -481,6 +482,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case newChatItem(user: User, chatItem: AChatItem)
|
||||
case chatItemStatusUpdated(user: User, chatItem: AChatItem)
|
||||
case chatItemUpdated(user: User, chatItem: AChatItem)
|
||||
case chatItemNotChanged(user: User, chatItem: AChatItem)
|
||||
case chatItemReaction(user: User, added: Bool, reaction: ACIReaction)
|
||||
case chatItemDeleted(user: User, deletedChatItem: AChatItem, toChatItem: AChatItem?, byUser: Bool)
|
||||
case contactsList(user: User, contacts: [Contact])
|
||||
@@ -583,6 +585,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .sentConfirmation: return "sentConfirmation"
|
||||
case .sentInvitation: return "sentInvitation"
|
||||
case .contactAlreadyExists: return "contactAlreadyExists"
|
||||
case .contactRequestAlreadyAccepted: return "contactRequestAlreadyAccepted"
|
||||
case .contactDeleted: return "contactDeleted"
|
||||
case .chatCleared: return "chatCleared"
|
||||
case .userProfileNoChange: return "userProfileNoChange"
|
||||
@@ -612,6 +615,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .newChatItem: return "newChatItem"
|
||||
case .chatItemStatusUpdated: return "chatItemStatusUpdated"
|
||||
case .chatItemUpdated: return "chatItemUpdated"
|
||||
case .chatItemNotChanged: return "chatItemNotChanged"
|
||||
case .chatItemReaction: return "chatItemReaction"
|
||||
case .chatItemDeleted: return "chatItemDeleted"
|
||||
case .contactsList: return "contactsList"
|
||||
@@ -713,6 +717,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .sentConfirmation: return noDetails
|
||||
case .sentInvitation: return noDetails
|
||||
case let .contactAlreadyExists(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .contactRequestAlreadyAccepted(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .contactDeleted(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .chatCleared(u, chatInfo): return withUser(u, String(describing: chatInfo))
|
||||
case .userProfileNoChange: return noDetails
|
||||
@@ -742,6 +747,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case let .newChatItem(u, chatItem): return withUser(u, String(describing: chatItem))
|
||||
case let .chatItemStatusUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
|
||||
case let .chatItemUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
|
||||
case let .chatItemNotChanged(u, chatItem): return withUser(u, String(describing: chatItem))
|
||||
case let .chatItemReaction(u, added, reaction): return withUser(u, "added: \(added)\n\(String(describing: reaction))")
|
||||
case let .chatItemDeleted(u, deletedChatItem, toChatItem, byUser): return withUser(u, "deletedChatItem:\n\(String(describing: deletedChatItem))\ntoChatItem:\n\(String(describing: toChatItem))\nbyUser: \(byUser)")
|
||||
case let .contactsList(u, contacts): return withUser(u, String(describing: contacts))
|
||||
@@ -1367,14 +1373,32 @@ public enum ChatError: Decodable {
|
||||
|
||||
public enum ChatErrorType: Decodable {
|
||||
case noActiveUser
|
||||
case noConnectionUser(agentConnId: String)
|
||||
case noSndFileUser(agentSndFileId: String)
|
||||
case noRcvFileUser(agentRcvFileId: String)
|
||||
case userUnknown
|
||||
case activeUserExists
|
||||
case userExists
|
||||
case differentActiveUser
|
||||
case differentActiveUser(commandUserId: Int64, activeUserId: Int64)
|
||||
case cantDeleteActiveUser(userId: Int64)
|
||||
case cantDeleteLastUser(userId: Int64)
|
||||
case cantHideLastUser(userId: Int64)
|
||||
case hiddenUserAlwaysMuted(userId: Int64)
|
||||
case emptyUserPassword(userId: Int64)
|
||||
case userAlreadyHidden(userId: Int64)
|
||||
case userNotHidden(userId: Int64)
|
||||
case chatNotStarted
|
||||
case chatNotStopped
|
||||
case chatStoreChanged
|
||||
case invalidConnReq
|
||||
case invalidChatMessage(message: String)
|
||||
case invalidChatMessage(connection: Connection, message: String)
|
||||
case contactNotReady(contact: Contact)
|
||||
case groupUserRole
|
||||
case contactDisabled(contact: Contact)
|
||||
case connectionDisabled(connection: Connection)
|
||||
case groupUserRole(groupInfo: GroupInfo, requiredRole: GroupMemberRole)
|
||||
case groupMemberInitialRole(groupInfo: GroupInfo, initialRole: GroupMemberRole)
|
||||
case contactIncognitoCantInvite
|
||||
case groupIncognitoCantInvite
|
||||
case groupContactRole(contactName: ContactName)
|
||||
case groupDuplicateMember(contactName: ContactName)
|
||||
case groupDuplicateMemberId
|
||||
@@ -1386,23 +1410,49 @@ public enum ChatErrorType: Decodable {
|
||||
case groupCantResendInvitation(groupInfo: GroupInfo, contactName: ContactName)
|
||||
case groupInternal(message: String)
|
||||
case fileNotFound(message: String)
|
||||
case fileSize(filePath: String)
|
||||
case fileAlreadyReceiving(message: String)
|
||||
case fileCancelled(message: String)
|
||||
case fileCancel(fileId: Int64, message: String)
|
||||
case fileAlreadyExists(filePath: String)
|
||||
case fileRead(filePath: String, message: String)
|
||||
case fileWrite(filePath: String, message: String)
|
||||
case fileSend(fileId: Int64, agentError: String)
|
||||
case fileRcvChunk(message: String)
|
||||
case fileInternal(message: String)
|
||||
case fileImageType(filePath: String)
|
||||
case fileImageSize(filePath: String)
|
||||
case fileNotReceived(fileId: Int64)
|
||||
// case xFTPRcvFile
|
||||
// case xFTPSndFile
|
||||
case fallbackToSMPProhibited(fileId: Int64)
|
||||
case inlineFileProhibited(fileId: Int64)
|
||||
case invalidQuote
|
||||
case invalidChatItemUpdate
|
||||
case invalidChatItemDelete
|
||||
case hasCurrentCall
|
||||
case noCurrentCall
|
||||
case callContact(contactId: Int64)
|
||||
case callState
|
||||
case directMessagesProhibited(contact: Contact)
|
||||
case agentVersion
|
||||
case agentNoSubResult(agentConnId: String)
|
||||
case commandError(message: String)
|
||||
case serverProtocol
|
||||
case agentCommandError(message: String)
|
||||
case invalidFileDescription(message: String)
|
||||
case internalError(message: String)
|
||||
case exception(message: String)
|
||||
}
|
||||
|
||||
public enum StoreError: Decodable {
|
||||
case duplicateName
|
||||
case userNotFound(userId: Int64)
|
||||
case userNotFoundByName(contactName: ContactName)
|
||||
case userNotFoundByContactId(contactId: Int64)
|
||||
case userNotFoundByGroupId(groupId: Int64)
|
||||
case userNotFoundByFileId(fileId: Int64)
|
||||
case userNotFoundByContactRequestId(contactRequestId: Int64)
|
||||
case contactNotFound(contactId: Int64)
|
||||
case contactNotFoundByName(contactName: ContactName)
|
||||
case contactNotReady(contactName: ContactName)
|
||||
@@ -1412,6 +1462,9 @@ public enum StoreError: Decodable {
|
||||
case contactRequestNotFoundByName(contactName: ContactName)
|
||||
case groupNotFound(groupId: Int64)
|
||||
case groupNotFoundByName(groupName: GroupName)
|
||||
case groupMemberNameNotFound(groupId: Int64, groupMemberName: ContactName)
|
||||
case groupMemberNotFound(groupMemberId: Int64)
|
||||
case groupMemberNotFoundByMemberId(memberId: String)
|
||||
case groupWithoutUser
|
||||
case duplicateGroupMember
|
||||
case groupAlreadyJoined
|
||||
@@ -1419,9 +1472,16 @@ public enum StoreError: Decodable {
|
||||
case sndFileNotFound(fileId: Int64)
|
||||
case sndFileInvalid(fileId: Int64)
|
||||
case rcvFileNotFound(fileId: Int64)
|
||||
case rcvFileDescrNotFound(fileId: Int64)
|
||||
case fileNotFound(fileId: Int64)
|
||||
case rcvFileInvalid(fileId: Int64)
|
||||
case rcvFileInvalidDescrPart
|
||||
case sharedMsgIdNotFoundByFileId(fileId: Int64)
|
||||
case fileIdNotFoundBySharedMsgId(sharedMsgId: String)
|
||||
case sndFileNotFoundXFTP(agentSndFileId: String)
|
||||
case rcvFileNotFoundXFTP(agentRcvFileId: String)
|
||||
case connectionNotFound(agentConnId: String)
|
||||
case connectionNotFoundById(connId: Int64)
|
||||
case pendingConnectionNotFound(connId: Int64)
|
||||
case introNotFound
|
||||
case uniqueID
|
||||
@@ -1429,11 +1489,16 @@ public enum StoreError: Decodable {
|
||||
case noMsgDelivery(connId: Int64, agentMsgId: String)
|
||||
case badChatItem(itemId: Int64)
|
||||
case chatItemNotFound(itemId: Int64)
|
||||
case quotedChatItemNotFound
|
||||
case chatItemNotFoundByText(text: String)
|
||||
case chatItemSharedMsgIdNotFound(sharedMsgId: String)
|
||||
case chatItemNotFoundByFileId(fileId: Int64)
|
||||
case chatItemNotFoundByGroupId(groupId: Int64)
|
||||
case profileNotFound(profileId: Int64)
|
||||
case duplicateGroupLink(groupInfo: GroupInfo)
|
||||
case groupLinkNotFound(groupInfo: GroupInfo)
|
||||
case hostMemberIdNotFound(groupId: Int64)
|
||||
case contactNotFoundByFileId(fileId: Int64)
|
||||
case noGroupSndStatus(itemId: Int64, groupMemberId: Int64)
|
||||
}
|
||||
|
||||
public enum DatabaseError: Decodable {
|
||||
@@ -1453,11 +1518,12 @@ public enum AgentErrorType: Decodable {
|
||||
case CMD(cmdErr: CommandErrorType)
|
||||
case CONN(connErr: ConnectionErrorType)
|
||||
case SMP(smpErr: ProtocolErrorType)
|
||||
case XFTP(xftpErr: XFTPErrorType)
|
||||
case NTF(ntfErr: ProtocolErrorType)
|
||||
case XFTP(xftpErr: XFTPErrorType)
|
||||
case BROKER(brokerAddress: String, brokerErr: BrokerErrorType)
|
||||
case AGENT(agentErr: SMPAgentError)
|
||||
case INTERNAL(internalErr: String)
|
||||
case INACTIVE
|
||||
}
|
||||
|
||||
public enum CommandErrorType: Decodable {
|
||||
@@ -1477,9 +1543,10 @@ public enum ConnectionErrorType: Decodable {
|
||||
}
|
||||
|
||||
public enum BrokerErrorType: Decodable {
|
||||
case RESPONSE(smpErr: ProtocolErrorType)
|
||||
case RESPONSE(smpErr: String)
|
||||
case UNEXPECTED
|
||||
case NETWORK
|
||||
case HOST
|
||||
case TRANSPORT(transportErr: ProtocolTransportError)
|
||||
case TIMEOUT
|
||||
}
|
||||
@@ -1513,6 +1580,7 @@ public enum XFTPErrorType: Decodable {
|
||||
public enum ProtocolCommandError: Decodable {
|
||||
case UNKNOWN
|
||||
case SYNTAX
|
||||
case PROHIBITED
|
||||
case NO_AUTH
|
||||
case HAS_AUTH
|
||||
case NO_ENTITY
|
||||
@@ -1535,7 +1603,9 @@ public enum SMPAgentError: Decodable {
|
||||
case A_MESSAGE
|
||||
case A_PROHIBITED
|
||||
case A_VERSION
|
||||
case A_ENCRYPTION
|
||||
case A_CRYPTO
|
||||
case A_DUPLICATE
|
||||
case A_QUEUE(queueErr: String)
|
||||
}
|
||||
|
||||
public enum ArchiveError: Decodable {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
local.properties
|
||||
common/src/commonMain/cpp/android/libs/
|
||||
common/src/commonMain/cpp/desktop/libs/
|
||||
common/src/commonMain/resources/libs/
|
||||
desktop/src/jvmMain/resources/libs/
|
||||
android/build
|
||||
android/release
|
||||
common/build
|
||||
|
||||
+5
-3
@@ -49,7 +49,7 @@ object ChatModel {
|
||||
val chatDbStatus = mutableStateOf<DBMigrationResult?>(null)
|
||||
val chats = mutableStateListOf<Chat>()
|
||||
// map of connections network statuses, key is agent connection id
|
||||
val networkStatuses = mutableStateMapOf<String, NetworkStatus>()
|
||||
val networkStatuses = mutableStateOf<Map<String, NetworkStatus>>(mapOf())
|
||||
|
||||
// current chat
|
||||
val chatId = mutableStateOf<String?>(null)
|
||||
@@ -477,11 +477,13 @@ object ChatModel {
|
||||
}
|
||||
|
||||
fun setContactNetworkStatus(contact: Contact, status: NetworkStatus) {
|
||||
networkStatuses[contact.activeConn.agentConnId] = status
|
||||
val statuses = networkStatuses.value.toMutableMap()
|
||||
statuses[contact.activeConn.agentConnId] = status
|
||||
networkStatuses.value = statuses
|
||||
}
|
||||
|
||||
fun contactNetworkStatus(contact: Contact): NetworkStatus =
|
||||
networkStatuses[contact.activeConn.agentConnId] ?: NetworkStatus.Unknown()
|
||||
networkStatuses.value[contact.activeConn.agentConnId] ?: NetworkStatus.Unknown()
|
||||
|
||||
fun addTerminalItem(item: TerminalItem) {
|
||||
if (terminalItems.value.size >= 500) {
|
||||
|
||||
+290
-38
@@ -1678,9 +1678,11 @@ object ChatController {
|
||||
}
|
||||
|
||||
private fun updateContactsStatus(contactRefs: List<ContactRef>, status: NetworkStatus) {
|
||||
val statuses = chatModel.networkStatuses.value.toMutableMap()
|
||||
for (c in contactRefs) {
|
||||
chatModel.networkStatuses[c.agentConnId] = status
|
||||
statuses[c.agentConnId] = status
|
||||
}
|
||||
chatModel.networkStatuses.value = statuses
|
||||
}
|
||||
|
||||
private fun processContactSubError(contact: Contact, chatError: ChatError) {
|
||||
@@ -3250,6 +3252,7 @@ sealed class CR {
|
||||
@Serializable @SerialName("sentConfirmation") class SentConfirmation(val user: User): CR()
|
||||
@Serializable @SerialName("sentInvitation") class SentInvitation(val user: User): CR()
|
||||
@Serializable @SerialName("contactAlreadyExists") class ContactAlreadyExists(val user: User, val contact: Contact): CR()
|
||||
@Serializable @SerialName("contactRequestAlreadyAccepted") class ContactRequestAlreadyAccepted(val user: User, val contact: Contact): CR()
|
||||
@Serializable @SerialName("contactDeleted") class ContactDeleted(val user: User, val contact: Contact): CR()
|
||||
@Serializable @SerialName("chatCleared") class ChatCleared(val user: User, val chatInfo: ChatInfo): CR()
|
||||
@Serializable @SerialName("userProfileNoChange") class UserProfileNoChange(val user: User): CR()
|
||||
@@ -3279,6 +3282,7 @@ sealed class CR {
|
||||
@Serializable @SerialName("newChatItem") class NewChatItem(val user: User, val chatItem: AChatItem): CR()
|
||||
@Serializable @SerialName("chatItemStatusUpdated") class ChatItemStatusUpdated(val user: User, val chatItem: AChatItem): CR()
|
||||
@Serializable @SerialName("chatItemUpdated") class ChatItemUpdated(val user: User, val chatItem: AChatItem): CR()
|
||||
@Serializable @SerialName("chatItemNotChanged") class ChatItemNotChanged(val user: User, val chatItem: AChatItem): CR()
|
||||
@Serializable @SerialName("chatItemReaction") class ChatItemReaction(val user: User, val added: Boolean, val reaction: ACIReaction): CR()
|
||||
@Serializable @SerialName("chatItemDeleted") class ChatItemDeleted(val user: User, val deletedChatItem: AChatItem, val toChatItem: AChatItem? = null, val byUser: Boolean): CR()
|
||||
@Serializable @SerialName("contactsList") class ContactsList(val user: User, val contacts: List<Contact>): CR()
|
||||
@@ -3376,6 +3380,7 @@ sealed class CR {
|
||||
is SentConfirmation -> "sentConfirmation"
|
||||
is SentInvitation -> "sentInvitation"
|
||||
is ContactAlreadyExists -> "contactAlreadyExists"
|
||||
is ContactRequestAlreadyAccepted -> "contactRequestAlreadyAccepted"
|
||||
is ContactDeleted -> "contactDeleted"
|
||||
is ChatCleared -> "chatCleared"
|
||||
is UserProfileNoChange -> "userProfileNoChange"
|
||||
@@ -3405,6 +3410,7 @@ sealed class CR {
|
||||
is NewChatItem -> "newChatItem"
|
||||
is ChatItemStatusUpdated -> "chatItemStatusUpdated"
|
||||
is ChatItemUpdated -> "chatItemUpdated"
|
||||
is ChatItemNotChanged -> "chatItemNotChanged"
|
||||
is ChatItemReaction -> "chatItemReaction"
|
||||
is ChatItemDeleted -> "chatItemDeleted"
|
||||
is ContactsList -> "contactsList"
|
||||
@@ -3499,6 +3505,7 @@ sealed class CR {
|
||||
is SentConfirmation -> withUser(user, noDetails())
|
||||
is SentInvitation -> withUser(user, noDetails())
|
||||
is ContactAlreadyExists -> withUser(user, json.encodeToString(contact))
|
||||
is ContactRequestAlreadyAccepted -> withUser(user, json.encodeToString(contact))
|
||||
is ContactDeleted -> withUser(user, json.encodeToString(contact))
|
||||
is ChatCleared -> withUser(user, json.encodeToString(chatInfo))
|
||||
is UserProfileNoChange -> withUser(user, noDetails())
|
||||
@@ -3529,6 +3536,7 @@ sealed class CR {
|
||||
is NewChatItem -> withUser(user, json.encodeToString(chatItem))
|
||||
is ChatItemStatusUpdated -> withUser(user, json.encodeToString(chatItem))
|
||||
is ChatItemUpdated -> withUser(user, json.encodeToString(chatItem))
|
||||
is ChatItemNotChanged -> withUser(user, json.encodeToString(chatItem))
|
||||
is ChatItemReaction -> withUser(user, "added: $added\n${json.encodeToString(reaction)}")
|
||||
is ChatItemDeleted -> withUser(user, "deletedChatItem:\n${json.encodeToString(deletedChatItem)}\ntoChatItem:\n${json.encodeToString(toChatItem)}\nbyUser: $byUser")
|
||||
is ContactsList -> withUser(user, json.encodeToString(contacts))
|
||||
@@ -3734,34 +3742,266 @@ sealed class ChatError {
|
||||
|
||||
@Serializable
|
||||
sealed class ChatErrorType {
|
||||
val string: String get() = when (this) {
|
||||
is NoActiveUser -> "noActiveUser"
|
||||
is DifferentActiveUser -> "differentActiveUser"
|
||||
is UserExists -> "userExists"
|
||||
is InvalidConnReq -> "invalidConnReq"
|
||||
is FileAlreadyReceiving -> "fileAlreadyReceiving"
|
||||
is СommandError -> "commandError $message"
|
||||
is CEException -> "exception $message"
|
||||
}
|
||||
@Serializable @SerialName("noActiveUser") class NoActiveUser: ChatErrorType()
|
||||
@Serializable @SerialName("differentActiveUser") class DifferentActiveUser: ChatErrorType()
|
||||
val string: String
|
||||
get() = when (this) {
|
||||
is NoActiveUser -> "noActiveUser"
|
||||
is NoConnectionUser -> "noConnectionUser"
|
||||
is NoSndFileUser -> "noSndFileUser"
|
||||
is NoRcvFileUser -> "noRcvFileUser"
|
||||
is UserUnknown -> "userUnknown"
|
||||
is ActiveUserExists -> "activeUserExists"
|
||||
is UserExists -> "userExists"
|
||||
is DifferentActiveUser -> "differentActiveUser"
|
||||
is CantDeleteActiveUser -> "cantDeleteActiveUser"
|
||||
is CantDeleteLastUser -> "cantDeleteLastUser"
|
||||
is CantHideLastUser -> "cantHideLastUser"
|
||||
is HiddenUserAlwaysMuted -> "hiddenUserAlwaysMuted"
|
||||
is EmptyUserPassword -> "emptyUserPassword"
|
||||
is UserAlreadyHidden -> "userAlreadyHidden"
|
||||
is UserNotHidden -> "userNotHidden"
|
||||
is ChatNotStarted -> "chatNotStarted"
|
||||
is ChatNotStopped -> "chatNotStopped"
|
||||
is ChatStoreChanged -> "chatStoreChanged"
|
||||
is InvalidConnReq -> "invalidConnReq"
|
||||
is InvalidChatMessage -> "invalidChatMessage"
|
||||
is ContactNotReady -> "contactNotReady"
|
||||
is ContactDisabled -> "contactDisabled"
|
||||
is ConnectionDisabled -> "connectionDisabled"
|
||||
is GroupUserRole -> "groupUserRole"
|
||||
is GroupMemberInitialRole -> "groupMemberInitialRole"
|
||||
is ContactIncognitoCantInvite -> "contactIncognitoCantInvite"
|
||||
is GroupIncognitoCantInvite -> "groupIncognitoCantInvite"
|
||||
is GroupContactRole -> "groupContactRole"
|
||||
is GroupDuplicateMember -> "groupDuplicateMember"
|
||||
is GroupDuplicateMemberId -> "groupDuplicateMemberId"
|
||||
is GroupNotJoined -> "groupNotJoined"
|
||||
is GroupMemberNotActive -> "groupMemberNotActive"
|
||||
is GroupMemberUserRemoved -> "groupMemberUserRemoved"
|
||||
is GroupMemberNotFound -> "groupMemberNotFound"
|
||||
is GroupMemberIntroNotFound -> "groupMemberIntroNotFound"
|
||||
is GroupCantResendInvitation -> "groupCantResendInvitation"
|
||||
is GroupInternal -> "groupInternal"
|
||||
is FileNotFound -> "fileNotFound"
|
||||
is FileSize -> "fileSize"
|
||||
is FileAlreadyReceiving -> "fileAlreadyReceiving"
|
||||
is FileCancelled -> "fileCancelled"
|
||||
is FileCancel -> "fileCancel"
|
||||
is FileAlreadyExists -> "fileAlreadyExists"
|
||||
is FileRead -> "fileRead"
|
||||
is FileWrite -> "fileWrite"
|
||||
is FileSend -> "fileSend"
|
||||
is FileRcvChunk -> "fileRcvChunk"
|
||||
is FileInternal -> "fileInternal"
|
||||
is FileImageType -> "fileImageType"
|
||||
is FileImageSize -> "fileImageSize"
|
||||
is FileNotReceived -> "fileNotReceived"
|
||||
// is XFTPRcvFile -> "xftpRcvFile"
|
||||
// is XFTPSndFile -> "xftpSndFile"
|
||||
is FallbackToSMPProhibited -> "fallbackToSMPProhibited"
|
||||
is InlineFileProhibited -> "inlineFileProhibited"
|
||||
is InvalidQuote -> "invalidQuote"
|
||||
is InvalidChatItemUpdate -> "invalidChatItemUpdate"
|
||||
is InvalidChatItemDelete -> "invalidChatItemDelete"
|
||||
is HasCurrentCall -> "hasCurrentCall"
|
||||
is NoCurrentCall -> "noCurrentCall"
|
||||
is CallContact -> "callContact"
|
||||
is CallState -> "callState"
|
||||
is DirectMessagesProhibited -> "directMessagesProhibited"
|
||||
is AgentVersion -> "agentVersion"
|
||||
is AgentNoSubResult -> "agentNoSubResult"
|
||||
is CommandError -> "commandError $message"
|
||||
is ServerProtocol -> "serverProtocol"
|
||||
is AgentCommandError -> "agentCommandError"
|
||||
is InvalidFileDescription -> "invalidFileDescription"
|
||||
is InternalError -> "internalError"
|
||||
is CEException -> "exception $message"
|
||||
}
|
||||
|
||||
@Serializable @SerialName("noActiveUser") object NoActiveUser: ChatErrorType()
|
||||
@Serializable @SerialName("noConnectionUser") class NoConnectionUser(val agentConnId: String): ChatErrorType()
|
||||
@Serializable @SerialName("noSndFileUser") class NoSndFileUser(val agentSndFileId: String): ChatErrorType()
|
||||
@Serializable @SerialName("noRcvFileUser") class NoRcvFileUser(val agentRcvFileId: String): ChatErrorType()
|
||||
@Serializable @SerialName("userUnknown") object UserUnknown: ChatErrorType()
|
||||
@Serializable @SerialName("activeUserExists") object ActiveUserExists: ChatErrorType()
|
||||
@Serializable @SerialName("userExists") class UserExists(val contactName: String): ChatErrorType()
|
||||
@Serializable @SerialName("invalidConnReq") class InvalidConnReq: ChatErrorType()
|
||||
@Serializable @SerialName("fileAlreadyReceiving") class FileAlreadyReceiving: ChatErrorType()
|
||||
@Serializable @SerialName("commandError") class СommandError(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("differentActiveUser") class DifferentActiveUser(val commandUserId: Long, val activeUserId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("cantDeleteActiveUser") class CantDeleteActiveUser(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("cantDeleteLastUser") class CantDeleteLastUser(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("cantHideLastUser") class CantHideLastUser(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("hiddenUserAlwaysMuted") class HiddenUserAlwaysMuted(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("emptyUserPassword") class EmptyUserPassword(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("userAlreadyHidden") class UserAlreadyHidden(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("userNotHidden") class UserNotHidden(val userId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("chatNotStarted") object ChatNotStarted: ChatErrorType()
|
||||
@Serializable @SerialName("chatNotStopped") object ChatNotStopped: ChatErrorType()
|
||||
@Serializable @SerialName("chatStoreChanged") object ChatStoreChanged: ChatErrorType()
|
||||
@Serializable @SerialName("invalidConnReq") object InvalidConnReq: ChatErrorType()
|
||||
@Serializable @SerialName("invalidChatMessage") class InvalidChatMessage(val connection: Connection, val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("contactNotReady") class ContactNotReady(val contact: Contact): ChatErrorType()
|
||||
@Serializable @SerialName("contactDisabled") class ContactDisabled(val contact: Contact): ChatErrorType()
|
||||
@Serializable @SerialName("connectionDisabled") class ConnectionDisabled(val connection: Connection): ChatErrorType()
|
||||
@Serializable @SerialName("groupUserRole") class GroupUserRole(val groupInfo: GroupInfo, val requiredRole: GroupMemberRole): ChatErrorType()
|
||||
@Serializable @SerialName("groupMemberInitialRole") class GroupMemberInitialRole(val groupInfo: GroupInfo, val initialRole: GroupMemberRole): ChatErrorType()
|
||||
@Serializable @SerialName("contactIncognitoCantInvite") object ContactIncognitoCantInvite: ChatErrorType()
|
||||
@Serializable @SerialName("groupIncognitoCantInvite") object GroupIncognitoCantInvite: ChatErrorType()
|
||||
@Serializable @SerialName("groupContactRole") class GroupContactRole(val contactName: String): ChatErrorType()
|
||||
@Serializable @SerialName("groupDuplicateMember") class GroupDuplicateMember(val contactName: String): ChatErrorType()
|
||||
@Serializable @SerialName("groupDuplicateMemberId") object GroupDuplicateMemberId: ChatErrorType()
|
||||
@Serializable @SerialName("groupNotJoined") class GroupNotJoined(val groupInfo: GroupInfo): ChatErrorType()
|
||||
@Serializable @SerialName("groupMemberNotActive") object GroupMemberNotActive: ChatErrorType()
|
||||
@Serializable @SerialName("groupMemberUserRemoved") object GroupMemberUserRemoved: ChatErrorType()
|
||||
@Serializable @SerialName("groupMemberNotFound") object GroupMemberNotFound: ChatErrorType()
|
||||
@Serializable @SerialName("groupMemberIntroNotFound") class GroupMemberIntroNotFound(val contactName: String): ChatErrorType()
|
||||
@Serializable @SerialName("groupCantResendInvitation") class GroupCantResendInvitation(val groupInfo: GroupInfo, val contactName: String): ChatErrorType()
|
||||
@Serializable @SerialName("groupInternal") class GroupInternal(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileNotFound") class FileNotFound(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileSize") class FileSize(val filePath: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileAlreadyReceiving") class FileAlreadyReceiving(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileCancelled") class FileCancelled(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileCancel") class FileCancel(val fileId: Long, val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileAlreadyExists") class FileAlreadyExists(val filePath: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileRead") class FileRead(val filePath: String, val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileWrite") class FileWrite(val filePath: String, val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileSend") class FileSend(val fileId: Long, val agentError: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileRcvChunk") class FileRcvChunk(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileInternal") class FileInternal(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileImageType") class FileImageType(val filePath: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileImageSize") class FileImageSize(val filePath: String): ChatErrorType()
|
||||
@Serializable @SerialName("fileNotReceived") class FileNotReceived(val fileId: Long): ChatErrorType()
|
||||
// @Serializable @SerialName("xFTPRcvFile") object XFTPRcvFile: ChatErrorType()
|
||||
// @Serializable @SerialName("xFTPSndFile") object XFTPSndFile: ChatErrorType()
|
||||
@Serializable @SerialName("fallbackToSMPProhibited") class FallbackToSMPProhibited(val fileId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("inlineFileProhibited") class InlineFileProhibited(val fileId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("invalidQuote") object InvalidQuote: ChatErrorType()
|
||||
@Serializable @SerialName("invalidChatItemUpdate") object InvalidChatItemUpdate: ChatErrorType()
|
||||
@Serializable @SerialName("invalidChatItemDelete") object InvalidChatItemDelete: ChatErrorType()
|
||||
@Serializable @SerialName("hasCurrentCall") object HasCurrentCall: ChatErrorType()
|
||||
@Serializable @SerialName("noCurrentCall") object NoCurrentCall: ChatErrorType()
|
||||
@Serializable @SerialName("callContact") class CallContact(val contactId: Long): ChatErrorType()
|
||||
@Serializable @SerialName("callState") object CallState: ChatErrorType()
|
||||
@Serializable @SerialName("directMessagesProhibited") class DirectMessagesProhibited(val contact: Contact): ChatErrorType()
|
||||
@Serializable @SerialName("agentVersion") object AgentVersion: ChatErrorType()
|
||||
@Serializable @SerialName("agentNoSubResult") class AgentNoSubResult(val agentConnId: String): ChatErrorType()
|
||||
@Serializable @SerialName("commandError") class CommandError(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("serverProtocol") object ServerProtocol: ChatErrorType()
|
||||
@Serializable @SerialName("agentCommandError") class AgentCommandError(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("invalidFileDescription") class InvalidFileDescription(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("internalError") class InternalError(val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("exception") class CEException(val message: String): ChatErrorType()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class StoreError {
|
||||
val string: String get() = when (this) {
|
||||
is UserContactLinkNotFound -> "userContactLinkNotFound"
|
||||
is GroupNotFound -> "groupNotFound"
|
||||
is DuplicateName -> "duplicateName"
|
||||
}
|
||||
@Serializable @SerialName("userContactLinkNotFound") class UserContactLinkNotFound: StoreError()
|
||||
@Serializable @SerialName("groupNotFound") class GroupNotFound: StoreError()
|
||||
@Serializable @SerialName("duplicateName") class DuplicateName: StoreError()
|
||||
val string: String
|
||||
get() = when (this) {
|
||||
is DuplicateName -> "duplicateName"
|
||||
is UserNotFound -> "userNotFound"
|
||||
is UserNotFoundByName -> "userNotFoundByName"
|
||||
is UserNotFoundByContactId -> "userNotFoundByContactId"
|
||||
is UserNotFoundByGroupId -> "userNotFoundByGroupId"
|
||||
is UserNotFoundByFileId -> "userNotFoundByFileId"
|
||||
is UserNotFoundByContactRequestId -> "userNotFoundByContactRequestId"
|
||||
is ContactNotFound -> "contactNotFound"
|
||||
is ContactNotFoundByName -> "contactNotFoundByName"
|
||||
is ContactNotReady -> "contactNotReady"
|
||||
is DuplicateContactLink -> "duplicateContactLink"
|
||||
is UserContactLinkNotFound -> "userContactLinkNotFound"
|
||||
is ContactRequestNotFound -> "contactRequestNotFound"
|
||||
is ContactRequestNotFoundByName -> "contactRequestNotFoundByName"
|
||||
is GroupNotFound -> "groupNotFound"
|
||||
is GroupNotFoundByName -> "groupNotFoundByName"
|
||||
is GroupMemberNameNotFound -> "groupMemberNameNotFound"
|
||||
is GroupMemberNotFound -> "groupMemberNotFound"
|
||||
is GroupMemberNotFoundByMemberId -> "groupMemberNotFoundByMemberId"
|
||||
is GroupWithoutUser -> "groupWithoutUser"
|
||||
is DuplicateGroupMember -> "duplicateGroupMember"
|
||||
is GroupAlreadyJoined -> "groupAlreadyJoined"
|
||||
is GroupInvitationNotFound -> "groupInvitationNotFound"
|
||||
is SndFileNotFound -> "sndFileNotFound"
|
||||
is SndFileInvalid -> "sndFileInvalid"
|
||||
is RcvFileNotFound -> "rcvFileNotFound"
|
||||
is RcvFileDescrNotFound -> "rcvFileDescrNotFound"
|
||||
is FileNotFound -> "fileNotFound"
|
||||
is RcvFileInvalid -> "rcvFileInvalid"
|
||||
is RcvFileInvalidDescrPart -> "rcvFileInvalidDescrPart"
|
||||
is SharedMsgIdNotFoundByFileId -> "sharedMsgIdNotFoundByFileId"
|
||||
is FileIdNotFoundBySharedMsgId -> "fileIdNotFoundBySharedMsgId"
|
||||
is SndFileNotFoundXFTP -> "sndFileNotFoundXFTP"
|
||||
is RcvFileNotFoundXFTP -> "rcvFileNotFoundXFTP"
|
||||
is ConnectionNotFound -> "connectionNotFound"
|
||||
is ConnectionNotFoundById -> "connectionNotFoundById"
|
||||
is PendingConnectionNotFound -> "pendingConnectionNotFound"
|
||||
is IntroNotFound -> "introNotFound"
|
||||
is UniqueID -> "uniqueID"
|
||||
is InternalError -> "internalError"
|
||||
is NoMsgDelivery -> "noMsgDelivery"
|
||||
is BadChatItem -> "badChatItem"
|
||||
is ChatItemNotFound -> "chatItemNotFound"
|
||||
is ChatItemNotFoundByText -> "chatItemNotFoundByText"
|
||||
is ChatItemSharedMsgIdNotFound -> "chatItemSharedMsgIdNotFound"
|
||||
is ChatItemNotFoundByFileId -> "chatItemNotFoundByFileId"
|
||||
is ChatItemNotFoundByGroupId -> "chatItemNotFoundByGroupId"
|
||||
is ProfileNotFound -> "profileNotFound"
|
||||
is DuplicateGroupLink -> "duplicateGroupLink"
|
||||
is GroupLinkNotFound -> "groupLinkNotFound"
|
||||
is HostMemberIdNotFound -> "hostMemberIdNotFound"
|
||||
is ContactNotFoundByFileId -> "contactNotFoundByFileId"
|
||||
is NoGroupSndStatus -> "noGroupSndStatus"
|
||||
}
|
||||
|
||||
@Serializable @SerialName("duplicateName") object DuplicateName: StoreError()
|
||||
@Serializable @SerialName("userNotFound") class UserNotFound(val userId: Long): StoreError()
|
||||
@Serializable @SerialName("userNotFoundByName") class UserNotFoundByName(val contactName: String): StoreError()
|
||||
@Serializable @SerialName("userNotFoundByContactId") class UserNotFoundByContactId(val contactId: Long): StoreError()
|
||||
@Serializable @SerialName("userNotFoundByGroupId") class UserNotFoundByGroupId(val groupId: Long): StoreError()
|
||||
@Serializable @SerialName("userNotFoundByFileId") class UserNotFoundByFileId(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("userNotFoundByContactRequestId") class UserNotFoundByContactRequestId(val contactRequestId: Long): StoreError()
|
||||
@Serializable @SerialName("contactNotFound") class ContactNotFound(val contactId: Long): StoreError()
|
||||
@Serializable @SerialName("contactNotFoundByName") class ContactNotFoundByName(val contactName: String): StoreError()
|
||||
@Serializable @SerialName("contactNotReady") class ContactNotReady(val contactName: String): StoreError()
|
||||
@Serializable @SerialName("duplicateContactLink") object DuplicateContactLink: StoreError()
|
||||
@Serializable @SerialName("userContactLinkNotFound") object UserContactLinkNotFound: StoreError()
|
||||
@Serializable @SerialName("contactRequestNotFound") class ContactRequestNotFound(val contactRequestId: Long): StoreError()
|
||||
@Serializable @SerialName("contactRequestNotFoundByName") class ContactRequestNotFoundByName(val contactName: String): StoreError()
|
||||
@Serializable @SerialName("groupNotFound") class GroupNotFound(val groupId: Long): StoreError()
|
||||
@Serializable @SerialName("groupNotFoundByName") class GroupNotFoundByName(val groupName: String): StoreError()
|
||||
@Serializable @SerialName("groupMemberNameNotFound") class GroupMemberNameNotFound(val groupId: Long, val groupMemberName: String): StoreError()
|
||||
@Serializable @SerialName("groupMemberNotFound") class GroupMemberNotFound(val groupMemberId: Long): StoreError()
|
||||
@Serializable @SerialName("groupMemberNotFoundByMemberId") class GroupMemberNotFoundByMemberId(val memberId: String): StoreError()
|
||||
@Serializable @SerialName("groupWithoutUser") object GroupWithoutUser: StoreError()
|
||||
@Serializable @SerialName("duplicateGroupMember") object DuplicateGroupMember: StoreError()
|
||||
@Serializable @SerialName("groupAlreadyJoined") object GroupAlreadyJoined: StoreError()
|
||||
@Serializable @SerialName("groupInvitationNotFound") object GroupInvitationNotFound: StoreError()
|
||||
@Serializable @SerialName("sndFileNotFound") class SndFileNotFound(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("sndFileInvalid") class SndFileInvalid(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("rcvFileNotFound") class RcvFileNotFound(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("rcvFileDescrNotFound") class RcvFileDescrNotFound(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("fileNotFound") class FileNotFound(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("rcvFileInvalid") class RcvFileInvalid(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("rcvFileInvalidDescrPart") object RcvFileInvalidDescrPart: StoreError()
|
||||
@Serializable @SerialName("sharedMsgIdNotFoundByFileId") class SharedMsgIdNotFoundByFileId(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("fileIdNotFoundBySharedMsgId") class FileIdNotFoundBySharedMsgId(val sharedMsgId: String): StoreError()
|
||||
@Serializable @SerialName("sndFileNotFoundXFTP") class SndFileNotFoundXFTP(val agentSndFileId: String): StoreError()
|
||||
@Serializable @SerialName("rcvFileNotFoundXFTP") class RcvFileNotFoundXFTP(val agentRcvFileId: String): StoreError()
|
||||
@Serializable @SerialName("connectionNotFound") class ConnectionNotFound(val agentConnId: String): StoreError()
|
||||
@Serializable @SerialName("connectionNotFoundById") class ConnectionNotFoundById(val connId: Long): StoreError()
|
||||
@Serializable @SerialName("pendingConnectionNotFound") class PendingConnectionNotFound(val connId: Long): StoreError()
|
||||
@Serializable @SerialName("introNotFound") object IntroNotFound: StoreError()
|
||||
@Serializable @SerialName("uniqueID") object UniqueID: StoreError()
|
||||
@Serializable @SerialName("internalError") class InternalError(val message: String): StoreError()
|
||||
@Serializable @SerialName("noMsgDelivery") class NoMsgDelivery(val connId: Long, val agentMsgId: String): StoreError()
|
||||
@Serializable @SerialName("badChatItem") class BadChatItem(val itemId: Long): StoreError()
|
||||
@Serializable @SerialName("chatItemNotFound") class ChatItemNotFound(val itemId: Long): StoreError()
|
||||
@Serializable @SerialName("chatItemNotFoundByText") class ChatItemNotFoundByText(val text: String): StoreError()
|
||||
@Serializable @SerialName("chatItemSharedMsgIdNotFound") class ChatItemSharedMsgIdNotFound(val sharedMsgId: String): StoreError()
|
||||
@Serializable @SerialName("chatItemNotFoundByFileId") class ChatItemNotFoundByFileId(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("chatItemNotFoundByGroupId") class ChatItemNotFoundByGroupId(val groupId: Long): StoreError()
|
||||
@Serializable @SerialName("profileNotFound") class ProfileNotFound(val profileId: Long): StoreError()
|
||||
@Serializable @SerialName("duplicateGroupLink") class DuplicateGroupLink(val groupInfo: GroupInfo): StoreError()
|
||||
@Serializable @SerialName("groupLinkNotFound") class GroupLinkNotFound(val groupInfo: GroupInfo): StoreError()
|
||||
@Serializable @SerialName("hostMemberIdNotFound") class HostMemberIdNotFound(val groupId: Long): StoreError()
|
||||
@Serializable @SerialName("contactNotFoundByFileId") class ContactNotFoundByFileId(val fileId: Long): StoreError()
|
||||
@Serializable @SerialName("noGroupSndStatus") class NoGroupSndStatus(val itemId: Long, val groupMemberId: Long): StoreError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -3792,18 +4032,22 @@ sealed class AgentErrorType {
|
||||
is CMD -> "CMD ${cmdErr.string}"
|
||||
is CONN -> "CONN ${connErr.string}"
|
||||
is SMP -> "SMP ${smpErr.string}"
|
||||
// is NTF -> "NTF ${ntfErr.string}"
|
||||
is XFTP -> "XFTP ${xftpErr.string}"
|
||||
is BROKER -> "BROKER ${brokerErr.string}"
|
||||
is AGENT -> "AGENT ${agentErr.string}"
|
||||
is INTERNAL -> "INTERNAL $internalErr"
|
||||
is INACTIVE -> "INACTIVE"
|
||||
}
|
||||
@Serializable @SerialName("CMD") class CMD(val cmdErr: CommandErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("CONN") class CONN(val connErr: ConnectionErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("SMP") class SMP(val smpErr: SMPErrorType): AgentErrorType()
|
||||
// @Serializable @SerialName("NTF") class NTF(val ntfErr: SMPErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("XFTP") class XFTP(val xftpErr: XFTPErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("BROKER") class BROKER(val brokerAddress: String, val brokerErr: BrokerErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("AGENT") class AGENT(val agentErr: SMPAgentError): AgentErrorType()
|
||||
@Serializable @SerialName("INTERNAL") class INTERNAL(val internalErr: String): AgentErrorType()
|
||||
@Serializable @SerialName("INACTIVE") object INACTIVE: AgentErrorType()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -3841,17 +4085,19 @@ sealed class ConnectionErrorType {
|
||||
@Serializable
|
||||
sealed class BrokerErrorType {
|
||||
val string: String get() = when (this) {
|
||||
is RESPONSE -> "RESPONSE ${smpErr.string}"
|
||||
is RESPONSE -> "RESPONSE ${smpErr}"
|
||||
is UNEXPECTED -> "UNEXPECTED"
|
||||
is NETWORK -> "NETWORK"
|
||||
is HOST -> "HOST"
|
||||
is TRANSPORT -> "TRANSPORT ${transportErr.string}"
|
||||
is TIMEOUT -> "TIMEOUT"
|
||||
}
|
||||
@Serializable @SerialName("RESPONSE") class RESPONSE(val smpErr: SMPErrorType): BrokerErrorType()
|
||||
@Serializable @SerialName("UNEXPECTED") class UNEXPECTED: BrokerErrorType()
|
||||
@Serializable @SerialName("NETWORK") class NETWORK: BrokerErrorType()
|
||||
@Serializable @SerialName("RESPONSE") class RESPONSE(val smpErr: String): BrokerErrorType()
|
||||
@Serializable @SerialName("UNEXPECTED") object UNEXPECTED: BrokerErrorType()
|
||||
@Serializable @SerialName("NETWORK") object NETWORK: BrokerErrorType()
|
||||
@Serializable @SerialName("HOST") object HOST: BrokerErrorType()
|
||||
@Serializable @SerialName("TRANSPORT") class TRANSPORT(val transportErr: SMPTransportError): BrokerErrorType()
|
||||
@Serializable @SerialName("TIMEOUT") class TIMEOUT: BrokerErrorType()
|
||||
@Serializable @SerialName("TIMEOUT") object TIMEOUT: BrokerErrorType()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -3881,15 +4127,17 @@ sealed class ProtocolCommandError {
|
||||
val string: String get() = when (this) {
|
||||
is UNKNOWN -> "UNKNOWN"
|
||||
is SYNTAX -> "SYNTAX"
|
||||
is PROHIBITED -> "PROHIBITED"
|
||||
is NO_AUTH -> "NO_AUTH"
|
||||
is HAS_AUTH -> "HAS_AUTH"
|
||||
is NO_QUEUE -> "NO_QUEUE"
|
||||
}
|
||||
@Serializable @SerialName("UNKNOWN") class UNKNOWN: ProtocolCommandError()
|
||||
@Serializable @SerialName("SYNTAX") class SYNTAX: ProtocolCommandError()
|
||||
@Serializable @SerialName("NO_AUTH") class NO_AUTH: ProtocolCommandError()
|
||||
@Serializable @SerialName("HAS_AUTH") class HAS_AUTH: ProtocolCommandError()
|
||||
@Serializable @SerialName("NO_QUEUE") class NO_QUEUE: ProtocolCommandError()
|
||||
@Serializable @SerialName("UNKNOWN") object UNKNOWN: ProtocolCommandError()
|
||||
@Serializable @SerialName("SYNTAX") object SYNTAX: ProtocolCommandError()
|
||||
@Serializable @SerialName("PROHIBITED") object PROHIBITED: ProtocolCommandError()
|
||||
@Serializable @SerialName("NO_AUTH") object NO_AUTH: ProtocolCommandError()
|
||||
@Serializable @SerialName("HAS_AUTH") object HAS_AUTH: ProtocolCommandError()
|
||||
@Serializable @SerialName("NO_QUEUE") object NO_QUEUE: ProtocolCommandError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -3924,12 +4172,16 @@ sealed class SMPAgentError {
|
||||
is A_MESSAGE -> "A_MESSAGE"
|
||||
is A_PROHIBITED -> "A_PROHIBITED"
|
||||
is A_VERSION -> "A_VERSION"
|
||||
is A_ENCRYPTION -> "A_ENCRYPTION"
|
||||
is A_CRYPTO -> "A_CRYPTO"
|
||||
is A_DUPLICATE -> "A_DUPLICATE"
|
||||
is A_QUEUE -> "A_QUEUE"
|
||||
}
|
||||
@Serializable @SerialName("A_MESSAGE") class A_MESSAGE: SMPAgentError()
|
||||
@Serializable @SerialName("A_PROHIBITED") class A_PROHIBITED: SMPAgentError()
|
||||
@Serializable @SerialName("A_VERSION") class A_VERSION: SMPAgentError()
|
||||
@Serializable @SerialName("A_ENCRYPTION") class A_ENCRYPTION: SMPAgentError()
|
||||
@Serializable @SerialName("A_MESSAGE") object A_MESSAGE: SMPAgentError()
|
||||
@Serializable @SerialName("A_PROHIBITED") object A_PROHIBITED: SMPAgentError()
|
||||
@Serializable @SerialName("A_VERSION") object A_VERSION: SMPAgentError()
|
||||
@Serializable @SerialName("A_CRYPTO") object A_CRYPTO: SMPAgentError()
|
||||
@Serializable @SerialName("A_DUPLICATE") object A_DUPLICATE: SMPAgentError()
|
||||
@Serializable @SerialName("A_QUEUE") class A_QUEUE(val queueErr: String): SMPAgentError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ private fun sendCommand(chatModel: ChatModel, composeState: MutableState<Compose
|
||||
val prefPerformLA = chatModel.controller.appPrefs.performLA.get()
|
||||
val s = composeState.value.message
|
||||
if (s.startsWith("/sql") && (!prefPerformLA || !developerTools)) {
|
||||
val resp = CR.ChatCmdError(null, ChatError.ChatErrorChat(ChatErrorType.СommandError("Failed reading: empty")))
|
||||
val resp = CR.ChatCmdError(null, ChatError.ChatErrorChat(ChatErrorType.CommandError("Failed reading: empty")))
|
||||
chatModel.addTerminalItem(TerminalItem.cmd(CC.Console(s)))
|
||||
chatModel.addTerminalItem(TerminalItem.resp(resp))
|
||||
composeState.value = ComposeState(useLinkPreviews = false)
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ fun ChatInfoView(
|
||||
val connStats = remember { mutableStateOf(connectionStats) }
|
||||
val developerTools = chatModel.controller.appPrefs.developerTools.get()
|
||||
if (chat != null && currentUser != null) {
|
||||
val contactNetworkStatus = remember(chatModel.networkStatuses.toMap()) {
|
||||
val contactNetworkStatus = remember(chatModel.networkStatuses.value) {
|
||||
mutableStateOf(chatModel.contactNetworkStatus(contact))
|
||||
}
|
||||
val sendReceipts = remember { mutableStateOf(SendReceipts.fromBool(contact.chatSettings.sendRcpts, currentUser.sendRcptsContacts)) }
|
||||
|
||||
+18
-7
@@ -76,13 +76,7 @@ fun GroupMemberInfoView(
|
||||
}
|
||||
},
|
||||
connectViaAddress = { connReqUri ->
|
||||
val uri = URI(connReqUri)
|
||||
withUriAction(uri) { linkType ->
|
||||
withApi {
|
||||
Log.d(TAG, "connectViaUri: connecting")
|
||||
connectViaUri(chatModel, linkType, uri)
|
||||
}
|
||||
}
|
||||
connectViaMemberAddressAlert(connReqUri)
|
||||
},
|
||||
removeMember = { removeMemberDialog(groupInfo, member, chatModel, close) },
|
||||
onRoleSelected = {
|
||||
@@ -450,6 +444,23 @@ private fun updateMemberRoleDialog(
|
||||
)
|
||||
}
|
||||
|
||||
fun connectViaMemberAddressAlert(connReqUri: String) {
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.connect_via_member_address_alert_title),
|
||||
text = generalGetString(MR.strings.connect_via_member_address_alert_desc),
|
||||
confirmText = generalGetString(MR.strings.connect_via_link_verb),
|
||||
onConfirm = {
|
||||
val uri = URI(connReqUri)
|
||||
withUriAction(uri) { linkType ->
|
||||
withApi {
|
||||
Log.d(TAG, "connectViaUri: connecting")
|
||||
connectViaUri(chatModel, linkType, uri)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewGroupMemberInfoLayout() {
|
||||
|
||||
@@ -1212,6 +1212,8 @@
|
||||
<string name="change_member_role_question">Change group role?</string>
|
||||
<string name="member_role_will_be_changed_with_notification">The role will be changed to \"%s\". Everyone in the group will be notified.</string>
|
||||
<string name="member_role_will_be_changed_with_invitation">The role will be changed to \"%s\". The member will receive a new invitation.</string>
|
||||
<string name="connect_via_member_address_alert_title">Connect directly?</string>
|
||||
<string name="connect_via_member_address_alert_desc">Сonnection request will be sent to this group member.</string>
|
||||
<string name="error_removing_member">Error removing member</string>
|
||||
<string name="error_changing_role">Error changing role</string>
|
||||
<string name="info_row_group">Group</string>
|
||||
|
||||
+10
-1
@@ -1,5 +1,7 @@
|
||||
package chat.simplex.common.ui.theme
|
||||
|
||||
import chat.simplex.common.platform.Log
|
||||
import chat.simplex.common.platform.TAG
|
||||
import com.jthemedetecor.OsThemeDetector
|
||||
|
||||
private val detector: OsThemeDetector = OsThemeDetector.getDetector()
|
||||
@@ -7,4 +9,11 @@ private val detector: OsThemeDetector = OsThemeDetector.getDetector()
|
||||
registerListener(::reactOnDarkThemeChanges)
|
||||
}
|
||||
|
||||
actual fun isSystemInDarkTheme(): Boolean = detector.isDark
|
||||
actual fun isSystemInDarkTheme(): Boolean = try {
|
||||
detector.isDark
|
||||
}
|
||||
catch (e: Exception) {
|
||||
Log.e(TAG, e.stackTraceToString())
|
||||
/* On Mac this code can produce exception */
|
||||
false
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ afterEvaluate {
|
||||
copy {
|
||||
from("${project(":desktop").buildDir}/cmake/main/linux-amd64", "$cppPath/desktop/libs/linux-x86_64", "$cppPath/desktop/libs/linux-x86_64/deps")
|
||||
into("src/jvmMain/resources/libs/linux-x86_64")
|
||||
include("*.so")
|
||||
include("*.so*")
|
||||
eachFile {
|
||||
path = name
|
||||
}
|
||||
@@ -135,7 +135,7 @@ afterEvaluate {
|
||||
copy {
|
||||
from("${project(":desktop").buildDir}/cmake/main/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64", "$cppPath/desktop/libs/linux-aarch64/deps")
|
||||
into("src/jvmMain/resources/libs/linux-aarch64")
|
||||
include("*.so")
|
||||
include("*.so*")
|
||||
eachFile {
|
||||
path = name
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import qualified Data.Attoparsec.Text as A
|
||||
import Data.Char (isDigit)
|
||||
import Data.Either (fromRight)
|
||||
import Data.Functor (($>))
|
||||
import Data.List (intercalate)
|
||||
import Data.List (intercalate, foldl')
|
||||
import Data.List.NonEmpty (NonEmpty)
|
||||
import qualified Data.List.NonEmpty as L
|
||||
import Data.Maybe (fromMaybe, isNothing)
|
||||
@@ -124,9 +124,15 @@ unmarked :: Text -> Markdown
|
||||
unmarked = Markdown Nothing
|
||||
|
||||
parseMaybeMarkdownList :: Text -> Maybe MarkdownList
|
||||
parseMaybeMarkdownList s =
|
||||
let m = intercalate ["\n"] . map (markdownToList . parseMarkdown) $ T.lines s
|
||||
in if all (isNothing . format) m then Nothing else Just m
|
||||
parseMaybeMarkdownList s
|
||||
| all (isNothing . format) ml = Nothing
|
||||
| otherwise = Just . reverse $ foldl' acc [] ml
|
||||
where
|
||||
ml = intercalate ["\n"] . map (markdownToList . parseMarkdown) $ T.lines s
|
||||
acc [] m = [m]
|
||||
acc ms@(FormattedText f t : ms') ft@(FormattedText f' t')
|
||||
| f == f' = FormattedText f (t <> t') : ms'
|
||||
| otherwise = ft : ms
|
||||
|
||||
parseMarkdownList :: Text -> MarkdownList
|
||||
parseMarkdownList = markdownToList . parseMarkdown
|
||||
|
||||
@@ -204,5 +204,7 @@ multilineMarkdownList :: Spec
|
||||
multilineMarkdownList = describe "multiline markdown" do
|
||||
it "correct markdown" do
|
||||
parseMaybeMarkdownList "http://simplex.chat\nhttp://app.simplex.chat" `shouldBe` Just [uri' "http://simplex.chat", "\n", uri' "http://app.simplex.chat"]
|
||||
it "combines the same formats" do
|
||||
parseMaybeMarkdownList "http://simplex.chat\ntext 1\ntext 2\nhttp://app.simplex.chat" `shouldBe` Just [uri' "http://simplex.chat", "\ntext 1\ntext 2\n", uri' "http://app.simplex.chat"]
|
||||
it "no markdown" do
|
||||
parseMaybeMarkdownList "not a\nmarkdown" `shouldBe` Nothing
|
||||
|
||||
Reference in New Issue
Block a user