@ -435,12 +435,13 @@ export async function uploadOurAvatar(newAvatarDecrypted?: ArrayBuffer) {
}
}
// tslint:disable-next-line: max-func-body-length
export async function deleteMessagesById (
messageIds : Array < string > ,
conversationId : string ,
askUserForConfirmation : boolean
) {
const conversation Model = getConversationController ( ) . getOrThrow ( conversationId ) ;
const conversation = getConversationController ( ) . getOrThrow ( conversationId ) ;
const selectedMessages = _ . compact (
await Promise . all ( messageIds . map ( m = > getMessageById ( m , false ) ) )
) ;
@ -450,20 +451,20 @@ export async function deleteMessagesById(
// In future, we may be able to unsend private messages also
// isServerDeletable also defined in ConversationHeader.tsx for
// future reference
const isServerDeletable = conversation Model . isPublic ( ) ;
const isServerDeletable = conversation . isPublic ( ) ;
const doDelete = async ( ) = > {
const doDelete = async ( deleteForEveryone : boolean = true ) = > {
let toDeleteLocallyIds : Array < string > ;
const ourDevicePubkey = UserUtils . getOurPubKeyStrFromCache ( ) ;
if ( ! ourDevicePubkey ) {
return ;
}
const isAllOurs = selectedMessages . every ( message = > ourDevicePubkey === message . getSource ( ) ) ;
if ( isServerDeletable ) {
//#region open group v2 deletion
// Get our Moderator status
const ourDevicePubkey = UserUtils . getOurPubKeyStrFromCache ( ) ;
if ( ! ourDevicePubkey ) {
return ;
}
const isAdmin = conversationModel . isAdmin ( ourDevicePubkey ) ;
const isAllOurs = selectedMessages . every ( message = > ourDevicePubkey === message . getSource ( ) ) ;
const isAdmin = conversation . isAdmin ( ourDevicePubkey ) ;
if ( ! isAllOurs && ! isAdmin ) {
ToastUtils . pushMessageDeleteForbidden ( ) ;
@ -472,24 +473,38 @@ export async function deleteMessagesById(
return ;
}
toDeleteLocallyIds = await deleteOpenGroupMessages ( selectedMessages , conversation Model ) ;
toDeleteLocallyIds = await deleteOpenGroupMessages ( selectedMessages , conversation ) ;
if ( toDeleteLocallyIds . length === 0 ) {
// Message failed to delete from server, show error?
return ;
}
// successful deletion
ToastUtils . pushDeleted ( ) ;
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
//#endregion
} else {
toDeleteLocallyIds = selectedMessages . map ( m = > m . id as string ) ;
}
await Promise . all (
toDeleteLocallyIds . map ( async msgId = > {
await conversationModel . removeMessage ( msgId ) ;
} )
) ;
//#region deletion for 1-1 and closed groups
if ( ! isAllOurs ) {
ToastUtils . pushMessageDeleteForbidden ( ) ;
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
return ;
}
// Update view and trigger update
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
ToastUtils . pushDeleted ( ) ;
if ( window . lokiFeatureFlags ? . useUnsendRequests ) {
if ( deleteForEveryone ) {
void deleteForAll ( selectedMessages ) ;
} else {
void deleteForJustThisUser ( selectedMessages ) ;
}
} else {
//#region to remove once unsend enabled
await Promise . all ( messageIds . map ( msgId = > conversation . removeMessage ( msgId ) ) ) ;
ToastUtils . pushDeleted ( ) ;
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
//#endregion
}
//#endregion
}
} ;
if ( askUserForConfirmation ) {
@ -512,31 +527,83 @@ export async function deleteMessagesById(
const okText = window . i18n ( isServerDeletable ? 'deleteForEveryone' : 'delete' ) ;
const onClickClose = ( ) = > {
//#region confirmation for deletion of messages
const showDeletionTypeModal = ( ) = > {
window . inboxStore ? . dispatch ( updateConfirmModal ( null ) ) ;
window . inboxStore ? . dispatch (
updateConfirmModal ( {
title : window.i18n ( 'deletionTypeTitle' ) ,
okText : window.i18n ( 'deleteMessageForEveryoneLowercase' ) ,
okTheme : SessionButtonColor.Danger ,
onClickOk : async ( ) = > {
await doDelete ( true ) ;
} ,
cancelText : window.i18n ( 'deleteJustForMe' ) ,
onClickCancel : async ( ) = > {
await doDelete ( false ) ;
} ,
} )
) ;
return ;
} ;
const warningMessage = ( ( ) = > {
if ( isServerDeletable ) {
return moreThanOne
? window . i18n ( 'deleteMultiplePublicWarning' )
: window . i18n ( 'deletePublicWarning' ) ;
}
return moreThanOne ? window . i18n ( 'deleteMultipleWarning' ) : window . i18n ( 'deleteWarning' ) ;
} ) ( ) ;
window . inboxStore ? . dispatch (
updateConfirmModal ( {
title ,
message : warningMessage ,
message : window.i18n ( moreThanOne ? 'deleteMessagesQuestion' : 'deleteMessageQuestion' ) ,
okText ,
okTheme : SessionButtonColor.Danger ,
onClickOk : doDelete ,
onClickClose ,
onClickOk : async ( ) = > {
if ( isServerDeletable ) {
// unsend logic
await doDelete ( true ) ;
// explicity close modal for this case.
window . inboxStore ? . dispatch ( updateConfirmModal ( null ) ) ;
} else {
showDeletionTypeModal ( ) ;
}
} ,
closeAfterInput : false ,
} )
) ;
//#endregion
} else {
void doDelete ( ) ;
}
/ * *
* Deletes messages for everyone in a 1 - 1 or closed group conversation
* @param msgsToDelete Messages to delete
* /
async function deleteForAll ( msgsToDelete : Array < MessageModel > ) {
window ? . log ? . warn ( 'Deleting messages for all users in this conversation' ) ;
const result = await conversation . unsendMessages ( msgsToDelete ) ;
// TODO: may need to specify deletion for own device as well.
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
if ( result ) {
ToastUtils . pushDeleted ( ) ;
} else {
ToastUtils . someDeletionsFailed ( ) ;
}
}
/ * *
*
* @param toDeleteLocallyIds Messages to delete for just this user . Still sends an unsend message to sync
* with other devices
* /
async function deleteForJustThisUser ( msgsToDelete : Array < MessageModel > ) {
window ? . log ? . warn ( 'Deleting messages just for this user' ) ;
// is deleting on swarm sufficient or does it need to be unsent as well?
const deleteResult = await conversation . deleteMessages ( msgsToDelete ) ;
// Update view and trigger update
window . inboxStore ? . dispatch ( resetSelectedMessageIds ( ) ) ;
if ( deleteResult ) {
ToastUtils . pushDeleted ( ) ;
} else {
ToastUtils . someDeletionsFailed ( ) ;
}
}
}
export async function replyToMessage ( messageId : string ) {