From 7be68ea8d2601b1e5df894d632d1ab9194ce0ea9 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 1 Mar 2025 23:37:02 +0000 Subject: [PATCH] remove column, add UI types and group status icon --- apps/ios/Shared/Views/ChatList/ChatPreviewView.swift | 5 +++-- apps/ios/SimpleXChat/ChatTypes.swift | 5 +++++ .../kotlin/chat/simplex/common/model/ChatModel.kt | 5 +++++ .../simplex/common/views/chatlist/ChatPreviewView.kt | 5 +++-- .../common/src/commonMain/resources/MR/base/strings.xml | 2 ++ .../commonMain/resources/MR/images/ic_help_filled.svg | 1 + src/Simplex/Chat/Library/Subscriber.hs | 6 +++--- .../Postgres/Migrations/M20250227_member_acceptance.hs | 4 ---- src/Simplex/Chat/Store/Profiles.hs | 9 ++++----- .../SQLite/Migrations/M20250227_member_acceptance.hs | 4 ---- .../Chat/Store/SQLite/Migrations/chat_query_plans.txt | 2 +- src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql | 1 - 12 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help_filled.svg diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index 6969ae325c..d860c8e842 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -143,6 +143,7 @@ struct ChatPreviewView: View { } case let .group(groupInfo): switch (groupInfo.membership.memberStatus) { + case .memPendingApproval: inactiveIcon("questionmark.circle.fill") case .memRejected: inactiveIcon() case .memLeft: inactiveIcon() case .memRemoved: inactiveIcon() @@ -154,8 +155,8 @@ struct ChatPreviewView: View { } } - @ViewBuilder private func inactiveIcon() -> some View { - Image(systemName: "multiply.circle.fill") + private func inactiveIcon(_ icon: String = "multiply.circle.fill") -> some View { + Image(systemName: icon) .foregroundColor(.secondary.opacity(0.65)) .background(Circle().foregroundColor(Color(uiColor: .systemBackground))) } diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index a601e60d5f..468bc2ea8f 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -2147,6 +2147,7 @@ public struct GroupMember: Identifiable, Decodable, Hashable { case .memGroupDeleted: return false case .memUnknown: return false case .memInvited: return false + case .memPendingApproval: return true case .memIntroduced: return false case .memIntroInvited: return false case .memAccepted: return false @@ -2165,6 +2166,7 @@ public struct GroupMember: Identifiable, Decodable, Hashable { case .memGroupDeleted: return false case .memUnknown: return false case .memInvited: return false + case .memPendingApproval: return false case .memIntroduced: return true case .memIntroInvited: return true case .memAccepted: return true @@ -2296,6 +2298,7 @@ public enum GroupMemberStatus: String, Decodable, Hashable { case memGroupDeleted = "deleted" case memUnknown = "unknown" case memInvited = "invited" + case memPendingApproval = "pending_approval" case memIntroduced = "introduced" case memIntroInvited = "intro-inv" case memAccepted = "accepted" @@ -2312,6 +2315,7 @@ public enum GroupMemberStatus: String, Decodable, Hashable { case .memGroupDeleted: return "group deleted" case .memUnknown: return "unknown status" case .memInvited: return "invited" + case .memPendingApproval: return "pending approval" case .memIntroduced: return "connecting (introduced)" case .memIntroInvited: return "connecting (introduction invitation)" case .memAccepted: return "connecting (accepted)" @@ -2330,6 +2334,7 @@ public enum GroupMemberStatus: String, Decodable, Hashable { case .memGroupDeleted: return "group deleted" case .memUnknown: return "unknown" case .memInvited: return "invited" + case .memPendingApproval: return "pending" case .memIntroduced: return "connecting" case .memIntroInvited: return "connecting" case .memAccepted: return "connecting" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index f784dcb9ed..7afcd69487 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -1917,6 +1917,7 @@ data class GroupMember ( GroupMemberStatus.MemGroupDeleted -> false GroupMemberStatus.MemUnknown -> false GroupMemberStatus.MemInvited -> false + GroupMemberStatus.MemPendingApproval -> true GroupMemberStatus.MemIntroduced -> false GroupMemberStatus.MemIntroInvited -> false GroupMemberStatus.MemAccepted -> false @@ -1933,6 +1934,7 @@ data class GroupMember ( GroupMemberStatus.MemGroupDeleted -> false GroupMemberStatus.MemUnknown -> false GroupMemberStatus.MemInvited -> false + GroupMemberStatus.MemPendingApproval -> false GroupMemberStatus.MemIntroduced -> true GroupMemberStatus.MemIntroInvited -> true GroupMemberStatus.MemAccepted -> true @@ -2037,6 +2039,7 @@ enum class GroupMemberStatus { @SerialName("deleted") MemGroupDeleted, @SerialName("unknown") MemUnknown, @SerialName("invited") MemInvited, + @SerialName("pending_approval") MemPendingApproval, @SerialName("introduced") MemIntroduced, @SerialName("intro-inv") MemIntroInvited, @SerialName("accepted") MemAccepted, @@ -2052,6 +2055,7 @@ enum class GroupMemberStatus { MemGroupDeleted -> generalGetString(MR.strings.group_member_status_group_deleted) MemUnknown -> generalGetString(MR.strings.group_member_status_unknown) MemInvited -> generalGetString(MR.strings.group_member_status_invited) + MemPendingApproval -> generalGetString(MR.strings.group_member_status_pending_approval) MemIntroduced -> generalGetString(MR.strings.group_member_status_introduced) MemIntroInvited -> generalGetString(MR.strings.group_member_status_intro_invitation) MemAccepted -> generalGetString(MR.strings.group_member_status_accepted) @@ -2068,6 +2072,7 @@ enum class GroupMemberStatus { MemGroupDeleted -> generalGetString(MR.strings.group_member_status_group_deleted) MemUnknown -> generalGetString(MR.strings.group_member_status_unknown_short) MemInvited -> generalGetString(MR.strings.group_member_status_invited) + MemPendingApproval -> generalGetString(MR.strings.group_member_status_pending_approval_short) MemIntroduced -> generalGetString(MR.strings.group_member_status_connecting) MemIntroInvited -> generalGetString(MR.strings.group_member_status_connecting) MemAccepted -> generalGetString(MR.strings.group_member_status_connecting) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt index 93d512507a..3edefafa75 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt @@ -52,9 +52,9 @@ fun ChatPreviewView( val cInfo = chat.chatInfo @Composable - fun inactiveIcon() { + fun inactiveIcon(icon: ImageResource = MR.images.ic_cancel_filled) { Icon( - painterResource(MR.images.ic_cancel_filled), + painterResource(icon), stringResource(MR.strings.icon_descr_group_inactive), Modifier.size(18.sp.toDp()).background(MaterialTheme.colors.background, CircleShape), tint = MaterialTheme.colors.secondary @@ -70,6 +70,7 @@ fun ChatPreviewView( } is ChatInfo.Group -> when (cInfo.groupInfo.membership.memberStatus) { + GroupMemberStatus.MemPendingApproval -> inactiveIcon(MR.images.ic_help_filled) GroupMemberStatus.MemRejected -> inactiveIcon() GroupMemberStatus.MemLeft -> inactiveIcon() GroupMemberStatus.MemRemoved -> inactiveIcon() diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 83f085fe3a..3a2aee9623 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1632,6 +1632,8 @@ group deleted unknown status invited + pending approval + pending connecting (introduced) connecting (introduction invitation) connecting (accepted) diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help_filled.svg new file mode 100644 index 0000000000..ba3d3a393a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 2e9e4f85b6..90dc5b8d1a 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -581,7 +581,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = let (UserContactLink {autoAccept}, gli_) = ucl when (connChatVersion < batchSend2Version) $ sendAutoReply ct' autoAccept -- TODO REMOVE LEGACY vvv - forM_ gli_ $ \GroupLinkInfo {groupId, memberRole = gLinkMemRole, acceptance = _acceptance} -> do + forM_ gli_ $ \GroupLinkInfo {groupId, memberRole = gLinkMemRole} -> do groupInfo <- withStore $ \db -> getGroupInfo db vr user groupId subMode <- chatReadVar subscriptionMode groupConnIds <- createAgentConnectionAsync user CFCreateConnGrpInv True SCMInvitation subMode @@ -1205,10 +1205,10 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = incognitoProfile <- if acceptIncognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing ct <- acceptContactRequestAsync user cReq incognitoProfile reqPQSup toView $ CRAcceptingContactRequest user ct - Just gli@GroupLinkInfo {groupId, acceptance = gAcceptance, memberRole = gLinkMemRole} -> do + Just gli@GroupLinkInfo {groupId, memberRole = gLinkMemRole} -> do gInfo <- withStore $ \db -> getGroupInfo db vr user groupId acceptMember_ <- asks $ acceptMember . chatHooks . config - maybe (pure $ Right (gAcceptance, gLinkMemRole)) (\am -> liftIO $ am gInfo gli p) acceptMember_ >>= \case + maybe (pure $ Right (GAAuto, gLinkMemRole)) (\am -> liftIO $ am gInfo gli p) acceptMember_ >>= \case Right (acceptance, useRole) | v < groupFastLinkJoinVersion -> messageError "processUserContactRequest: chat version range incompatible for accepting group join request" diff --git a/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs b/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs index 68fa03868c..40d38ef4bc 100644 --- a/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs +++ b/src/Simplex/Chat/Store/Postgres/Migrations/M20250227_member_acceptance.hs @@ -10,8 +10,6 @@ m20250227_member_acceptance :: Text m20250227_member_acceptance = T.pack [r| -ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT; - DROP INDEX idx_chat_items_groups_history; CREATE INDEX idx_chat_items_groups_history ON chat_items( user_id, @@ -28,8 +26,6 @@ down_m20250227_member_acceptance :: Text down_m20250227_member_acceptance = T.pack [r| -ALTER TABLE user_contact_links DROP COLUMN group_link_auto_accept; - DROP INDEX idx_chat_items_groups_history; CREATE INDEX idx_chat_items_groups_history ON chat_items( user_id, diff --git a/src/Simplex/Chat/Store/Profiles.hs b/src/Simplex/Chat/Store/Profiles.hs index 38045500ce..22d2a7b1f5 100644 --- a/src/Simplex/Chat/Store/Profiles.hs +++ b/src/Simplex/Chat/Store/Profiles.hs @@ -457,7 +457,6 @@ data UserContactLink = UserContactLink data GroupLinkInfo = GroupLinkInfo { groupId :: GroupId, - acceptance :: GroupAcceptance, memberRole :: GroupMemberRole } deriving (Show) @@ -498,14 +497,14 @@ getUserContactLinkById db userId userContactLinkId = groupLinkInfoQuery :: Query groupLinkInfoQuery = [sql| - SELECT conn_req_contact, auto_accept, business_address, auto_accept_incognito, auto_reply_msg_content, group_id, group_link_auto_accept, group_link_member_role + SELECT conn_req_contact, auto_accept, business_address, auto_accept_incognito, auto_reply_msg_content, group_id, group_link_member_role FROM user_contact_links WHERE user_id = ? |] -toGroupLinkInfo :: (Maybe GroupId, Maybe GroupAcceptance, Maybe GroupMemberRole) -> Maybe GroupLinkInfo -toGroupLinkInfo (groupId_, acceptance_, mRole_) = - (\groupId -> GroupLinkInfo {groupId, acceptance = fromMaybe GAAuto acceptance_, memberRole = fromMaybe GRMember mRole_}) +toGroupLinkInfo :: (Maybe GroupId, Maybe GroupMemberRole) -> Maybe GroupLinkInfo +toGroupLinkInfo (groupId_, mRole_) = + (\groupId -> GroupLinkInfo {groupId, memberRole = fromMaybe GRMember mRole_}) <$> groupId_ getGroupLinkInfo :: DB.Connection -> UserId -> GroupId -> IO (Maybe GroupLinkInfo) diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs b/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs index 281b3063cd..6b3f287c7e 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs +++ b/src/Simplex/Chat/Store/SQLite/Migrations/M20250227_member_acceptance.hs @@ -8,8 +8,6 @@ import Database.SQLite.Simple.QQ (sql) m20250227_member_acceptance :: Query m20250227_member_acceptance = [sql| -ALTER TABLE user_contact_links ADD COLUMN group_link_auto_accept TEXT; - DROP INDEX idx_chat_items_groups_history; CREATE INDEX idx_chat_items_groups_history ON chat_items( user_id, @@ -25,8 +23,6 @@ CREATE INDEX idx_chat_items_groups_history ON chat_items( down_m20250227_member_acceptance :: Query down_m20250227_member_acceptance = [sql| -ALTER TABLE user_contact_links DROP COLUMN group_link_auto_accept; - DROP INDEX idx_chat_items_groups_history; CREATE INDEX idx_chat_items_groups_history ON chat_items( user_id, diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt index 063ca91faf..c72214fb36 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt @@ -2965,7 +2965,7 @@ Plan: SEARCH user_contact_links USING INDEX sqlite_autoindex_user_contact_links_1 (user_id=? AND local_display_name=?) Query: - SELECT conn_req_contact, auto_accept, business_address, auto_accept_incognito, auto_reply_msg_content, group_id, group_link_auto_accept, group_link_member_role + SELECT conn_req_contact, auto_accept, business_address, auto_accept_incognito, auto_reply_msg_content, group_id, group_link_member_role FROM user_contact_links WHERE user_id = ? AND user_contact_link_id = ? diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql b/src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql index d48806e953..45e91a46f8 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_schema.sql @@ -316,7 +316,6 @@ CREATE TABLE user_contact_links( group_link_id BLOB, group_link_member_role TEXT NULL, business_address INTEGER DEFAULT 0, - group_link_auto_accept TEXT, UNIQUE(user_id, local_display_name) ); CREATE TABLE contact_requests(