@@ -1829,7 +1829,10 @@ pub async fn delete_msgs_ex(
18291829 Ok ( ( ) )
18301830}
18311831
1832- /// Marks requested messages as seen.
1832+ /// Marks requested messages and reactions to them as seen.
1833+ /// NB: UIs should pass all messages to this function, incl. outgoing and info ones, as this is used
1834+ /// also for synchronization and to track last position. This should be called when a message comes
1835+ /// into view or when a reaction for a message being in view arrives.
18331836pub async fn markseen_msgs ( context : & Context , msg_ids : Vec < MsgId > ) -> Result < ( ) > {
18341837 if msg_ids. is_empty ( ) {
18351838 return Ok ( ( ) ) ;
@@ -1843,10 +1846,18 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
18431846
18441847 let mut msgs = Vec :: with_capacity ( msg_ids. len ( ) ) ;
18451848 for & id in & msg_ids {
1846- if let Some ( msg ) = context
1849+ let Some ( rfc724_mid ) : Option < String > = context
18471850 . sql
1848- . query_row_optional (
1851+ . query_get_value ( "SELECT rfc724_mid FROM msgs WHERE id=?" , ( id, ) )
1852+ . await ?
1853+ else {
1854+ continue ;
1855+ } ;
1856+ context
1857+ . sql
1858+ . query_map (
18491859 "SELECT
1860+ m.id AS id,
18501861 m.chat_id AS chat_id,
18511862 m.state AS state,
18521863 m.ephemeral_timer AS ephemeral_timer,
@@ -1857,9 +1868,11 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
18571868 c.archived AS archived,
18581869 c.blocked AS blocked
18591870 FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id
1860- WHERE m.id=? AND m.chat_id>9" ,
1861- ( id, ) ,
1871+ WHERE (m.id=? OR m.mime_in_reply_to=? AND m.hidden=1)
1872+ AND m.chat_id>9 AND ?<=m.state AND m.state<?" ,
1873+ ( id, rfc724_mid, MessageState :: InFresh , MessageState :: InSeen ) ,
18621874 |row| {
1875+ let id: MsgId = row. get ( "id" ) ?;
18631876 let chat_id: ChatId = row. get ( "chat_id" ) ?;
18641877 let state: MessageState = row. get ( "state" ) ?;
18651878 let param: Params = row. get :: < _ , String > ( "param" ) ?. parse ( ) . unwrap_or_default ( ) ;
@@ -1884,11 +1897,14 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
18841897 ephemeral_timer,
18851898 ) )
18861899 } ,
1900+ |rows| {
1901+ for row in rows {
1902+ msgs. push ( row?) ;
1903+ }
1904+ Ok ( ( ) )
1905+ } ,
18871906 )
1888- . await ?
1889- {
1890- msgs. push ( msg) ;
1891- }
1907+ . await ?;
18921908 }
18931909
18941910 if msgs
@@ -1917,48 +1933,45 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
19171933 _curr_ephemeral_timer,
19181934 ) in msgs
19191935 {
1920- if curr_state == MessageState :: InFresh || curr_state == MessageState :: InNoticed {
1921- update_msg_state ( context, id, MessageState :: InSeen ) . await ?;
1922- info ! ( context, "Seen message {}." , id) ;
1923-
1924- markseen_on_imap_table ( context, & curr_rfc724_mid) . await ?;
1925-
1926- // Read receipts for system messages are never sent to contacts.
1927- // These messages have no place to display received read receipt
1928- // anyway. And since their text is locally generated,
1929- // quoting them is dangerous as it may contain contact names. E.g., for original message
1930- // "Group left by me", a read receipt will quote "Group left by <name>", and the name can
1931- // be a display name stored in address book rather than the name sent in the From field by
1932- // the user.
1933- //
1934- // We also don't send read receipts for contact requests.
1935- // Read receipts will not be sent even after accepting the chat.
1936- let to_id = if curr_blocked == Blocked :: Not
1937- && !curr_hidden
1938- && curr_param. get_bool ( Param :: WantsMdn ) . unwrap_or_default ( )
1939- && curr_param. get_cmd ( ) == SystemMessage :: Unknown
1940- && context. should_send_mdns ( ) . await ?
1941- {
1942- Some ( curr_from_id)
1943- } else if context. get_config_bool ( Config :: BccSelf ) . await ? {
1944- Some ( ContactId :: SELF )
1945- } else {
1946- None
1947- } ;
1948- if let Some ( to_id) = to_id {
1949- context
1950- . sql
1951- . execute (
1952- "INSERT INTO smtp_mdns (msg_id, from_id, rfc724_mid) VALUES(?, ?, ?)" ,
1953- ( id, to_id, curr_rfc724_mid) ,
1954- )
1955- . await
1956- . context ( "failed to insert into smtp_mdns" ) ?;
1957- context. scheduler . interrupt_smtp ( ) . await ;
1958- }
1959- if !curr_hidden {
1960- updated_chat_ids. insert ( curr_chat_id) ;
1961- }
1936+ update_msg_state ( context, id, MessageState :: InSeen ) . await ?;
1937+ info ! ( context, "Seen message {}." , id) ;
1938+
1939+ markseen_on_imap_table ( context, & curr_rfc724_mid) . await ?;
1940+
1941+ // Read receipts for system messages are never sent to contacts. These messages have no
1942+ // place to display received read receipt anyway. And since their text is locally generated,
1943+ // quoting them is dangerous as it may contain contact names. E.g., for original message
1944+ // "Group left by me", a read receipt will quote "Group left by <name>", and the name can be
1945+ // a display name stored in address book rather than the name sent in the From field by the
1946+ // user.
1947+ //
1948+ // We also don't send read receipts for contact requests. Read receipts will not be sent
1949+ // even after accepting the chat.
1950+ let to_id = if curr_blocked == Blocked :: Not
1951+ && !curr_hidden
1952+ && curr_param. get_bool ( Param :: WantsMdn ) . unwrap_or_default ( )
1953+ && curr_param. get_cmd ( ) == SystemMessage :: Unknown
1954+ && context. should_send_mdns ( ) . await ?
1955+ {
1956+ Some ( curr_from_id)
1957+ } else if context. get_config_bool ( Config :: BccSelf ) . await ? {
1958+ Some ( ContactId :: SELF )
1959+ } else {
1960+ None
1961+ } ;
1962+ if let Some ( to_id) = to_id {
1963+ context
1964+ . sql
1965+ . execute (
1966+ "INSERT INTO smtp_mdns (msg_id, from_id, rfc724_mid) VALUES(?, ?, ?)" ,
1967+ ( id, to_id, curr_rfc724_mid) ,
1968+ )
1969+ . await
1970+ . context ( "failed to insert into smtp_mdns" ) ?;
1971+ context. scheduler . interrupt_smtp ( ) . await ;
1972+ }
1973+ if !curr_hidden {
1974+ updated_chat_ids. insert ( curr_chat_id) ;
19621975 }
19631976 archived_chats_maybe_noticed |= curr_state == MessageState :: InFresh
19641977 && !curr_hidden
0 commit comments