@@ -6,6 +6,7 @@ use std::collections::VecDeque;
6
6
use std:: path:: { Path , PathBuf } ;
7
7
use std:: str;
8
8
9
+ use anyhow:: bail;
9
10
use anyhow:: { Context as _, Result , ensure, format_err} ;
10
11
use deltachat_contact_tools:: { VcardContact , parse_vcard} ;
11
12
use deltachat_derive:: { FromSql , ToSql } ;
@@ -1717,25 +1718,26 @@ pub(crate) async fn delete_msg_locally(context: &Context, msg: &Message) -> Resu
1717
1718
pub ( crate ) async fn get_webxdc_info_messages (
1718
1719
context : & Context ,
1719
1720
msg : & Message ,
1720
- ) -> Result < Vec < MsgId > > {
1721
+ ) -> Result < Vec < ( MsgId , String ) > > {
1721
1722
let msg_ids = context
1722
1723
. sql
1723
1724
. query_map (
1724
- r#"SELECT id, param
1725
+ r#"SELECT id, rfc724_mid, param
1725
1726
FROM msgs
1726
1727
WHERE chat_id=?1 AND hidden=0 AND mime_in_reply_to = ?2
1727
1728
"# ,
1728
- ( msg. chat_id , msg. id ) ,
1729
+ ( msg. chat_id , & msg. rfc724_mid ) ,
1729
1730
|row| {
1730
1731
let info_msg_id: MsgId = row. get ( 0 ) ?;
1732
+ let info_msg_rfc724: String = row. get ( 1 ) ?;
1731
1733
let last_param: Params = row. get :: < _ , String > ( 2 ) ?. parse ( ) . unwrap_or_default ( ) ;
1732
- Ok ( ( info_msg_id, last_param) )
1734
+ Ok ( ( info_msg_id, info_msg_rfc724 , last_param) )
1733
1735
} ,
1734
1736
|row| {
1735
1737
Ok ( row
1736
1738
. filter_map ( Result :: ok)
1737
- . filter ( |( _, param) | param. get_cmd ( ) == SystemMessage :: WebxdcInfoMessage )
1738
- . map ( |( msg_id, _) | msg_id)
1739
+ . filter ( |( _, _ , param) | param. get_cmd ( ) == SystemMessage :: WebxdcInfoMessage )
1740
+ . map ( |( msg_id, rfc724 , _) | ( msg_id, rfc724 ) )
1739
1741
. collect :: < Vec < _ > > ( ) )
1740
1742
} ,
1741
1743
)
@@ -1781,9 +1783,9 @@ pub async fn delete_msgs_ex(
1781
1783
let mut modified_chat_ids = HashSet :: new ( ) ;
1782
1784
let mut deleted_rfc724_mid = Vec :: new ( ) ;
1783
1785
let mut res = Ok ( ( ) ) ;
1784
- let mut msg_ids_queue = VecDeque :: from_iter ( msg_ids . iter ( ) . cloned ( ) ) ;
1786
+ let mut deleted_info_msgs = Vec :: new ( ) ;
1785
1787
1786
- while let Some ( msg_id) = msg_ids_queue . pop_front ( ) {
1788
+ for & msg_id in msg_ids {
1787
1789
let msg = Message :: load_from_db ( context, msg_id) . await ?;
1788
1790
ensure ! (
1789
1791
!delete_for_all || msg. from_id == ContactId :: SELF ,
@@ -1794,7 +1796,7 @@ pub async fn delete_msgs_ex(
1794
1796
"Cannot request deletion of unencrypted message for others"
1795
1797
) ;
1796
1798
1797
- msg_ids_queue . extend ( get_webxdc_info_messages ( context, & msg) . await ?) ;
1799
+ deleted_info_msgs . extend ( get_webxdc_info_messages ( context, & msg) . await ?) ;
1798
1800
modified_chat_ids. insert ( msg. chat_id ) ;
1799
1801
deleted_rfc724_mid. push ( msg. rfc724_mid . clone ( ) ) ;
1800
1802
@@ -1815,22 +1817,23 @@ pub async fn delete_msgs_ex(
1815
1817
}
1816
1818
res?;
1817
1819
1820
+ let ( info_msg_ids, info_msg_rfc724) : ( Vec < MsgId > , Vec < _ > ) =
1821
+ deleted_info_msgs. into_iter ( ) . unzip ( ) ;
1822
+ if info_msg_rfc724. len ( ) > 0 && modified_chat_ids. len ( ) > 1 {
1823
+ bail ! ( "Can delete only from same chat." ) ;
1824
+ }
1825
+
1826
+ if let Some ( chat_id) = modified_chat_ids. iter ( ) . next ( ) {
1827
+ send_delete_request ( context, & info_msg_rfc724, chat_id) . await ?;
1828
+ }
1829
+
1818
1830
if delete_for_all {
1819
1831
ensure ! (
1820
1832
modified_chat_ids. len( ) == 1 ,
1821
1833
"Can delete only from same chat."
1822
1834
) ;
1823
1835
if let Some ( chat_id) = modified_chat_ids. iter ( ) . next ( ) {
1824
- let mut msg = Message :: new_text ( "🚮" . to_owned ( ) ) ;
1825
- // We don't want to send deletion requests in chats w/o encryption:
1826
- // - These are usually chats with non-DC clients who won't respect deletion requests
1827
- // anyway and display a weird trash bin message instead.
1828
- // - Deletion of world-visible unencrypted messages seems not very useful.
1829
- msg. param . set_int ( Param :: GuaranteeE2ee , 1 ) ;
1830
- msg. param
1831
- . set ( Param :: DeleteRequestFor , deleted_rfc724_mid. join ( " " ) ) ;
1832
- msg. hidden = true ;
1833
- send_msg ( context, * chat_id, & mut msg) . await ?;
1836
+ send_delete_request ( context, & deleted_rfc724_mid, chat_id) . await ?;
1834
1837
}
1835
1838
} else {
1836
1839
context
@@ -1840,6 +1843,11 @@ pub async fn delete_msgs_ex(
1840
1843
. await ?;
1841
1844
}
1842
1845
1846
+ for & msg_id in info_msg_ids. iter ( ) {
1847
+ let msg = Message :: load_from_db ( context, msg_id) . await ?;
1848
+ delete_msg_locally ( context, & msg) . await ?;
1849
+ }
1850
+
1843
1851
for & msg_id in msg_ids {
1844
1852
let msg = Message :: load_from_db ( context, msg_id) . await ?;
1845
1853
delete_msg_locally ( context, & msg) . await ?;
@@ -1852,6 +1860,20 @@ pub async fn delete_msgs_ex(
1852
1860
Ok ( ( ) )
1853
1861
}
1854
1862
1863
+ async fn send_delete_request (
1864
+ context : & Context ,
1865
+ deleted_rfc724_mid : & Vec < String > ,
1866
+ chat_id : & ChatId ,
1867
+ ) -> Result < ( ) , anyhow:: Error > {
1868
+ let mut msg = Message :: new_text ( "🚮" . to_owned ( ) ) ;
1869
+ msg. param . set_int ( Param :: GuaranteeE2ee , 1 ) ;
1870
+ msg. param
1871
+ . set ( Param :: DeleteRequestFor , deleted_rfc724_mid. join ( " " ) ) ;
1872
+ msg. hidden = true ;
1873
+ send_msg ( context, * chat_id, & mut msg) . await ?;
1874
+ Ok ( ( ) )
1875
+ }
1876
+
1855
1877
/// Marks requested messages as seen.
1856
1878
pub async fn markseen_msgs ( context : & Context , msg_ids : Vec < MsgId > ) -> Result < ( ) > {
1857
1879
if msg_ids. is_empty ( ) {
0 commit comments