diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 6b830b49b..8a925c841 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -148,6 +148,7 @@
"callsNotificationsRequired": "Voice and Video Calls require notifications to be enabled in your device system settings.",
"callsPermissionsRequired": "Call Permissions Required",
"callsPermissionsRequiredDescription": "You can enable the \"Voice and Video Calls\" permission in Privacy Settings.",
+ "callsPermissionsRequiredDescription1": "You can enable the \"Voice and Video Calls\" permission in Permissions Settings.",
"callsReconnecting": "Reconnecting…",
"callsRinging": "Ringing...",
"callsSessionCall": "{app_name} Call",
@@ -379,6 +380,7 @@
"groupCreateErrorNoMembers": "Please pick at least one other group member.",
"groupDelete": "Delete Group",
"groupDeleteDescription": "Are you sure you want to delete {group_name}? This will remove all members and delete all group content.",
+ "groupDeletedMemberDescription": "{group_name} has been deleted by a group admin. You will not be able to send any more messages.",
"groupDescriptionEnter": "Enter a group description",
"groupDisplayPictureUpdated": "Group display picture updated.",
"groupEdit": "Edit Group",
diff --git a/_locales/fa/messages.json b/_locales/fa/messages.json
index 9c9b4c745..52b9a5150 100644
--- a/_locales/fa/messages.json
+++ b/_locales/fa/messages.json
@@ -279,6 +279,7 @@
"deleteMessageDevicesAll": "حذف از تمام دستگاههایم",
"deleteMessageEveryone": "حذف برای همه",
"deleteMessageFailed": "{count, plural, one [خطا در حذف پیام] other [خطا در حذف پیام ها]}",
+ "deleteMessageWarning": "{count, plural, one [این پیام قابل حذف برای همه نیست] other [برخی از پیام هایی که انتخاب کرده اید را نمیتوان برای همه حذف کرد]}",
"deleteMessagesDescriptionEveryone": "آیا مطمئن هستید میخواهید این پیامها را برای همه حذف کنید؟",
"deleting": "در حال حذف",
"developerToolsToggle": "تاگل ابزار های توسعه دهنده",
@@ -382,6 +383,7 @@
"groupInviteFailedMultiple": "دعوت از {name} و {count} نفر دیگر به {group_name} انجام نشد",
"groupInviteFailedTwo": "دعوت از {name} و {other_name} به {group_name} انجام نشد",
"groupInviteFailedUser": "دعوت از {name} به {group_name} انجام نشد",
+ "groupInviteSending": "{count, plural, one [ارسال دعوت نامه] other [ارسال دعوت نامه ها]}",
"groupInviteSent": "دعوت نامه ارسال شد",
"groupInviteSuccessful": "دعوت به گروه موفقیتآمیز بود",
"groupInviteVersion": "کاربران باید آخرین نسخه را داشته باشند تا دعوتنامه دریافت کنند",
diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json
index 3fad75ef7..67928b2d1 100644
--- a/_locales/nl/messages.json
+++ b/_locales/nl/messages.json
@@ -35,6 +35,7 @@
"adminRemovedUser": "{name} is verwijderd als Admin.",
"adminRemovedUserMultiple": "{name} en {count} anderen zijn verwijderd als beheerder.",
"adminRemovedUserOther": "{name} en {other_name} zijn verwijderd als beheerder.",
+ "adminSendingPromotion": "{count, plural, one [Beheerder promotie versturen] other [Beheerder promoties versturen]}",
"adminSettings": "Admin instellingen",
"adminTwoPromotedToAdmin": "{name} en {other_name} zijn gepromoveerd tot Admin.",
"andMore": "+{count}",
@@ -274,9 +275,11 @@
"deleteAfterLegacyGroupsGroupUpdateErrorTitle": "Het is mislukt om de groep bij te werken",
"deleteAfterMessageDeletionStandardisationMessageDeletionForbidden": "Je hebt geen toestemming om andermans berichten te verwijderen",
"deleteMessage": "{count, plural, one [Verwijder bericht] other [Verwijder berichten]}",
+ "deleteMessageConfirm": "{count, plural, one [Weet u zeker dat u dit bericht wilt verwijderen?] other [Weet u zeker dat u deze berichten wilt verwijderen?]}",
"deleteMessageDeleted": "{count, plural, one [Bericht verwijderd] other [Berichten verwijderd]}",
"deleteMessageDeletedGlobally": "Dit bericht is verwijderd",
"deleteMessageDeletedLocally": "Dit bericht is op dit apparaat verwijderd",
+ "deleteMessageDescriptionDevice": "{count, plural, one [Weet u zeker dat u dit bericht enkel van dit apparaat wilt verwijderen?] other [Weet u zeker dat u deze berichten enkel van dit apparaat wilt verwijderen?]}",
"deleteMessageDescriptionEveryone": "Weet u zeker dat u dit bericht voor iedereen wilt verwijderen?",
"deleteMessageDeviceOnly": "Alleen verwijderen op dit apparaat",
"deleteMessageDevicesAll": "Verwijder op al mijn apparaten",
@@ -385,6 +388,7 @@
"groupInviteFailedMultiple": "Het uitnodigen van {name} en {count} anderen naar {group_name} is mislukt",
"groupInviteFailedTwo": "Het uitnodigen van {name} en {other_name} naar {group_name} is mislukt",
"groupInviteFailedUser": "Het uitnodigen van {name} naar {group_name} is mislukt",
+ "groupInviteSending": "{count, plural, one [Uitnodiging versturen] other [Uitnodigingen versturen]}",
"groupInviteSent": "Uitnodiging verzonden",
"groupInviteSuccessful": "Groepsuitnodiging succesvol",
"groupInviteVersion": "Gebruikers moeten de nieuwste versie hebben om uitnodigingen te ontvangen",
diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json
index 4b44f9e6a..d1d61fd05 100644
--- a/_locales/ru/messages.json
+++ b/_locales/ru/messages.json
@@ -274,9 +274,11 @@
"deleteAfterLegacyGroupsGroupUpdateErrorTitle": "Ошибка при обновлении группы",
"deleteAfterMessageDeletionStandardisationMessageDeletionForbidden": "У вас недостаточно прав для удаления других сообщений",
"deleteMessage": "{count, plural, one [Удалить Сообщение] few [Удалить сообщения] many [Удалить сообщения] other [Удалить сообщения]}",
+ "deleteMessageConfirm": "{count, plural, one [Вы уверены, что хотите удалить это сообщение?] few [Вы уверены, что хотите удалить эти сообщения?] many [Вы уверены, что хотите удалить эти сообщения?] other [Вы уверены, что хотите удалить эти сообщения?]}",
"deleteMessageDeleted": "{count, plural, one [Сообщение удалено] few [Сообщения удалены] many [Сообщения удалены] other [Сообщения удалены]}",
"deleteMessageDeletedGlobally": "Это сообщение было удалено",
"deleteMessageDeletedLocally": "Это сообщение было удалено на этом устройстве",
+ "deleteMessageDescriptionDevice": "{count, plural, one [Вы уверены, что хотите удалить это сообщение только с этого устройства?] few [Вы уверены, что хотите удалить эти сообщения только с этого устройства?] many [Вы уверены, что хотите удалить эти сообщения только с этого устройства?] other [Вы уверены, что хотите удалить эти сообщения только с этого устройства?]}",
"deleteMessageDescriptionEveryone": "Вы уверены, что хотите удалить это сообщение для всех?",
"deleteMessageDeviceOnly": "Удалить только на этом устройстве",
"deleteMessageDevicesAll": "Удалить на всех моих устройствах",
@@ -385,6 +387,7 @@
"groupInviteFailedMultiple": "Не удалось пригласить {name} и {count} других в {group_name}",
"groupInviteFailedTwo": "Не удалось пригласить {name} и {other_name} в {group_name}",
"groupInviteFailedUser": "Не удалось пригласить {name} в {group_name}",
+ "groupInviteSending": "{count, plural, one [Отправка приглашения] few [Отправка приглашений] many [Отправка приглашений] other [Отправка приглашений]}",
"groupInviteSent": "Приглашение отправлено",
"groupInviteSuccessful": "Приглашение в группу успешно",
"groupInviteVersion": "Пользователи должны иметь последнюю версию приложения для получения приглашений",
diff --git a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
index 04cefd52f..efbfb4ef9 100644
--- a/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
+++ b/ts/components/conversation/right-panel/overlay/OverlayRightPanelSettings.tsx
@@ -220,7 +220,7 @@ const DestroyGroupForAllMembersButton = () => {
onClickOk: () => {
void ConvoHub.use().deleteGroup(groupPk, {
deleteAllMessagesOnSwarm: true,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
fromSyncMessage: false,
sendLeaveMessage: false,
forceDestroyForAllMembers: true,
diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts
index 0a427c7bd..e4f4d42d5 100644
--- a/ts/interactions/conversationInteractions.ts
+++ b/ts/interactions/conversationInteractions.ts
@@ -223,7 +223,7 @@ export async function declineConversationWithoutConfirm({
// when deleting a 03 group message request, we also need to remove the conversation altogether
await ConvoHub.use().deleteGroup(conversationId, {
deleteAllMessagesOnSwarm: false,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
forceDestroyForAllMembers: false,
fromSyncMessage: false,
sendLeaveMessage: false,
@@ -418,7 +418,7 @@ async function leaveGroupOrCommunityByConvoId({
fromSyncMessage: false,
sendLeaveMessage,
deleteAllMessagesOnSwarm: false,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
forceDestroyForAllMembers: false,
});
}
diff --git a/ts/receiver/configMessage.ts b/ts/receiver/configMessage.ts
index 7edc62ad0..e89ff7a94 100644
--- a/ts/receiver/configMessage.ts
+++ b/ts/receiver/configMessage.ts
@@ -756,7 +756,7 @@ async function handleSingleGroupUpdateToLeave(toLeave: GroupPubkeyType) {
await ConvoHub.use().deleteGroup(toLeave, {
fromSyncMessage: true,
sendLeaveMessage: false,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
});
diff --git a/ts/receiver/groupv2/handleGroupV2Message.ts b/ts/receiver/groupv2/handleGroupV2Message.ts
index 90b79ae4f..47a4868c4 100644
--- a/ts/receiver/groupv2/handleGroupV2Message.ts
+++ b/ts/receiver/groupv2/handleGroupV2Message.ts
@@ -76,6 +76,7 @@ async function getInitializedGroupObject({
secretKey: null,
kicked: false,
invitePending: true,
+ destroyed: false,
};
}
diff --git a/ts/receiver/libsession/handleLibSessionMessage.ts b/ts/receiver/libsession/handleLibSessionMessage.ts
index ba537e8a3..e7975c5f3 100644
--- a/ts/receiver/libsession/handleLibSessionMessage.ts
+++ b/ts/receiver/libsession/handleLibSessionMessage.ts
@@ -54,7 +54,7 @@ async function handleLibSessionKickedMessage({
await ConvoHub.use().deleteGroup(groupPk, {
sendLeaveMessage: false,
fromSyncMessage: false,
- emptyGroupButKeepAsKicked: !inviteWasPending,
+ deletionType: inviteWasPending ? 'doNotKeep' : 'keepAsKicked',
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
});
diff --git a/ts/session/apis/snode_api/swarmPolling.ts b/ts/session/apis/snode_api/swarmPolling.ts
index 47a022221..74be4a403 100644
--- a/ts/session/apis/snode_api/swarmPolling.ts
+++ b/ts/session/apis/snode_api/swarmPolling.ts
@@ -681,7 +681,7 @@ export class SwarmPolling {
await ConvoHub.use().deleteGroup(pubkey, {
fromSyncMessage: true,
sendLeaveMessage: false,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
});
diff --git a/ts/session/apis/snode_api/swarm_polling_config/SwarmPollingGroupConfig.ts b/ts/session/apis/snode_api/swarm_polling_config/SwarmPollingGroupConfig.ts
index 94995ee54..b102826f2 100644
--- a/ts/session/apis/snode_api/swarm_polling_config/SwarmPollingGroupConfig.ts
+++ b/ts/session/apis/snode_api/swarm_polling_config/SwarmPollingGroupConfig.ts
@@ -44,7 +44,7 @@ async function handleMetaMergeResults(groupPk: GroupPubkeyType) {
await ConvoHub.use().deleteGroup(groupPk, {
sendLeaveMessage: false,
fromSyncMessage: false,
- emptyGroupButKeepAsKicked: true, // we just got something from the group's swarm, so it is not pendingInvite
+ deletionType: 'keepAsDestroyed', // we just got something from the group's swarm, so it is not pendingInvite
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
});
diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts
index 83c5bdfc0..4a5a312d7 100644
--- a/ts/session/conversations/ConversationController.ts
+++ b/ts/session/conversations/ConversationController.ts
@@ -253,12 +253,12 @@ class ConvoController {
{
sendLeaveMessage,
fromSyncMessage,
- emptyGroupButKeepAsKicked,
+ deletionType,
deleteAllMessagesOnSwarm,
forceDestroyForAllMembers,
}: DeleteOptions & {
sendLeaveMessage: boolean;
- emptyGroupButKeepAsKicked: boolean;
+ deletionType: 'doNotKeep' | 'keepAsKicked' | 'keepAsDestroyed';
deleteAllMessagesOnSwarm: boolean;
forceDestroyForAllMembers: boolean;
}
@@ -268,7 +268,7 @@ class ConvoController {
}
window.log.info(
- `deleteGroup: ${ed25519Str(groupPk)}, sendLeaveMessage:${sendLeaveMessage}, fromSyncMessage:${fromSyncMessage}, emptyGroupButKeepAsKicked:${emptyGroupButKeepAsKicked}, deleteAllMessagesOnSwarm:${deleteAllMessagesOnSwarm}, forceDestroyForAllMembers:${forceDestroyForAllMembers}`
+ `deleteGroup: ${ed25519Str(groupPk)}, sendLeaveMessage:${sendLeaveMessage}, fromSyncMessage:${fromSyncMessage}, deletionType:${deletionType}, deleteAllMessagesOnSwarm:${deleteAllMessagesOnSwarm}, forceDestroyForAllMembers:${forceDestroyForAllMembers}`
);
// this deletes all messages in the conversation
@@ -294,13 +294,13 @@ class ConvoController {
// when it was pendingInvite, we delete it fully,
// when it was not, we empty the group but keep it with the "you have been kicked" message
// Note: the pendingInvite=true case cannot really happen as we wouldn't be polling from that group (and so, not get the message kicking us)
- if (emptyGroupButKeepAsKicked) {
+ if (deletionType === 'keepAsKicked' || deletionType === 'keepAsDestroyed') {
// delete the secretKey/authData if we had it. If we need it for something, it has to be done before this call.
if (groupInUserGroup) {
groupInUserGroup.authData = null;
groupInUserGroup.secretKey = null;
groupInUserGroup.disappearingTimerSeconds = undefined;
- groupInUserGroup.kicked = true;
+
// we want to update the groupName in user group with whatever is in the groupInfo,
// so even if the group is not polled anymore, we have an up to date name on restore.
let nameInMetaGroup: string | undefined;
@@ -316,6 +316,11 @@ class ConvoController {
groupInUserGroup.name = nameInMetaGroup;
}
await UserGroupsWrapperActions.setGroup(groupInUserGroup);
+ if (deletionType === 'keepAsKicked') {
+ await UserGroupsWrapperActions.setGroupKicked(groupPk);
+ } else {
+ await UserGroupsWrapperActions.setGroupDestroyed(groupPk);
+ }
}
} else {
try {
diff --git a/ts/state/ducks/metaGroups.ts b/ts/state/ducks/metaGroups.ts
index f0ec70013..ef57e4a31 100644
--- a/ts/state/ducks/metaGroups.ts
+++ b/ts/state/ducks/metaGroups.ts
@@ -264,7 +264,7 @@ const initNewGroupInWrapper = createAsyncThunk(
await ConvoHub.use().deleteGroup(groupPk, {
fromSyncMessage: false,
sendLeaveMessage: false,
- emptyGroupButKeepAsKicked: false,
+ deletionType: 'doNotKeep',
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
});
diff --git a/ts/test/session/unit/crypto/SnodeSignatures_test.ts b/ts/test/session/unit/crypto/SnodeSignatures_test.ts
index c28ff1902..469dda2c9 100644
--- a/ts/test/session/unit/crypto/SnodeSignatures_test.ts
+++ b/ts/test/session/unit/crypto/SnodeSignatures_test.ts
@@ -43,6 +43,7 @@ function getEmptyUserGroup() {
name: '1243',
priority: 0,
pubkeyHex: validGroupPk,
+ destroyed: false,
} as UserGroupsGet;
}
diff --git a/ts/webworker/workers/browser/libsession_worker_interface.ts b/ts/webworker/workers/browser/libsession_worker_interface.ts
index 07c62a299..97ae9412e 100644
--- a/ts/webworker/workers/browser/libsession_worker_interface.ts
+++ b/ts/webworker/workers/browser/libsession_worker_interface.ts
@@ -62,7 +62,7 @@ type GenericWrapperActionsCalls = {
ed25519Key: Uint8Array,
dump: Uint8Array | null
) => Promise;
- free: ( wrapperId: ConfigWrapperUser ) => Promise;
+ free: (wrapperId: ConfigWrapperUser) => Promise;
confirmPushed: GenericWrapperActionsCall;
dump: GenericWrapperActionsCall;
makeDump: GenericWrapperActionsCall;
@@ -83,7 +83,6 @@ export const GenericWrapperActions: GenericWrapperActionsCalls = {
GenericWrapperActionsCalls['init']
>,
-
/** This function is used to free wrappers from memory only.
*
* See freeUserWrapper() in libsession.worker.ts */
@@ -346,6 +345,28 @@ export const UserGroupsWrapperActions: UserGroupsWrapperActionsCalls & {
return cloneDeep(group);
},
+ setGroupKicked: async (pubkeyHex: GroupPubkeyType) => {
+ const group = (await callLibSessionWorker([
+ 'UserGroupsConfig',
+ 'setGroupKicked',
+ pubkeyHex,
+ ])) as Awaited>;
+ groups.set(group.pubkeyHex, group);
+ dispatchCachedGroupsToRedux();
+ return cloneDeep(group);
+ },
+
+ setGroupDestroyed: async (pubkeyHex: GroupPubkeyType) => {
+ const group = (await callLibSessionWorker([
+ 'UserGroupsConfig',
+ 'setGroupDestroyed',
+ pubkeyHex,
+ ])) as Awaited>;
+ groups.set(group.pubkeyHex, group);
+ dispatchCachedGroupsToRedux();
+ return cloneDeep(group);
+ },
+
eraseGroup: async (pubkeyHex: GroupPubkeyType) => {
const ret = (await callLibSessionWorker([
'UserGroupsConfig',