Merge pull request #1942 from deltachat/add-msgs-seen-event

split DC_EVENT_MSGS_NOTICED off DC_EVENT_MSGS_CHANGED, remove dc_marknoticed_all_chats()
This commit is contained in:
bjoern
2020-09-25 21:41:10 +02:00
committed by GitHub
7 changed files with 55 additions and 88 deletions

View File

@@ -1122,8 +1122,8 @@ dc_array_t* dc_get_fresh_msgs (dc_context_t* context);
* but are still waiting for being marked as "seen" using dc_markseen_msgs()
* (IMAP/MDNs is not done for noticed messages).
*
* Calling this function usually results in the event #DC_EVENT_MSGS_CHANGED.
* See also dc_marknoticed_all_chats(), dc_marknoticed_contact() and dc_markseen_msgs().
* Calling this function usually results in the event #DC_EVENT_MSGS_NOTICED.
* See also dc_marknoticed_contact() and dc_markseen_msgs().
*
* @memberof dc_context_t
* @param context The context object as returned from dc_context_new().
@@ -1133,16 +1133,6 @@ dc_array_t* dc_get_fresh_msgs (dc_context_t* context);
void dc_marknoticed_chat (dc_context_t* context, uint32_t chat_id);
/**
* Same as dc_marknoticed_chat() but for _all_ chats.
*
* @memberof dc_context_t
* @param context The context object as returned from dc_context_new().
* @return None.
*/
void dc_marknoticed_all_chats (dc_context_t* context);
/**
* Returns all message IDs of the given types in a chat.
* Typically used to show a gallery.
@@ -1513,11 +1503,13 @@ void dc_forward_msgs (dc_context_t* context, const uint3
/**
* Mark all messages sent by the given contact
* as _noticed_. See also dc_marknoticed_chat() and
* dc_markseen_msgs()
* Mark all messages sent by the given contact as _noticed_.
* This function is typically used to ignore a user in the deaddrop temporarily ("Not now" button).
*
* Calling this function usually results in the event #DC_EVENT_MSGS_CHANGED.
* The contact is expected to belong to the deaddrop;
* only one #DC_EVENT_MSGS_NOTICED with chat_id=DC_CHAT_ID_DEADDROP may be emitted.
*
* See also dc_marknoticed_chat() and dc_markseen_msgs()
*
* @memberof dc_context_t
* @param context The context object.
@@ -1536,6 +1528,8 @@ void dc_marknoticed_contact (dc_context_t* context, uint32_t co
* Moreover, if messages belong to a chat with ephemeral messages enabled,
* the ephemeral timer is started for these messages.
*
* One #DC_EVENT_MSGS_NOTICED event is emitted per modified chat.
*
* @memberof dc_context_t
* @param context The context object.
* @param msg_ids An array of uint32_t containing all the messages IDs that should be marked as seen.
@@ -4607,6 +4601,20 @@ void dc_event_unref(dc_event_t* event);
#define DC_EVENT_INCOMING_MSG 2005
/**
* Messages were marked noticed or seen.
* The ui may update badge counters or stop showing a chatlist-item with a bold font.
*
* This event is emitted eg. when calling dc_markseen_msgs(), dc_marknoticed_chat() or dc_marknoticed_contact().
* Do not try to derive the state of an item from just the fact you received the event;
* use eg. dc_msg_get_state() or dc_get_fresh_msg_cnt() for this purpose.
*
* @param data1 (int) chat_id
* @param data2 0
*/
#define DC_EVENT_MSGS_NOTICED 2008
/**
* A single message is sent successfully. State changed from DC_STATE_OUT_PENDING to
* DC_STATE_OUT_DELIVERED, see dc_msg_get_state().

View File

@@ -362,6 +362,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc:
| EventType::ErrorSelfNotInGroup(_) => 0,
EventType::MsgsChanged { chat_id, .. }
| EventType::IncomingMsg { chat_id, .. }
| EventType::MsgsNoticed(chat_id)
| EventType::MsgDelivered { chat_id, .. }
| EventType::MsgFailed { chat_id, .. }
| EventType::MsgRead { chat_id, .. }
@@ -407,6 +408,7 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc:
| EventType::ConfigureProgress { .. }
| EventType::ImexProgress(_)
| EventType::ImexFileWritten(_)
| EventType::MsgsNoticed(_)
| EventType::ChatModified(_) => 0,
EventType::MsgsChanged { msg_id, .. }
| EventType::IncomingMsg { msg_id, .. }
@@ -446,6 +448,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut
}
EventType::MsgsChanged { .. }
| EventType::IncomingMsg { .. }
| EventType::MsgsNoticed(_)
| EventType::MsgDelivered { .. }
| EventType::MsgFailed { .. }
| EventType::MsgRead { .. }
@@ -970,22 +973,6 @@ pub unsafe extern "C" fn dc_marknoticed_chat(context: *mut dc_context_t, chat_id
})
}
#[no_mangle]
pub unsafe extern "C" fn dc_marknoticed_all_chats(context: *mut dc_context_t) {
if context.is_null() {
eprintln!("ignoring careless call to dc_marknoticed_all_chats()");
return;
}
let ctx = &*context;
block_on(async move {
chat::marknoticed_all_chats(&ctx)
.await
.log_err(ctx, "Failed marknoticed all chats")
.unwrap_or(())
})
}
fn from_prim<S, T>(s: S) -> Option<T>
where
T: FromPrimitive,

View File

@@ -882,7 +882,13 @@ class TestOnlineAccount:
lp.sec("mark messages as seen on ac2, wait for changes on ac1")
ac2.direct_imap.idle_start()
ac1.direct_imap.idle_start()
ac2.mark_seen_messages([msg2, msg4])
ev = ac2._evtracker.get_matching("DC_EVENT_MSGS_NOTICED")
assert msg2.chat.id == msg4.chat.id
assert ev.data1 == msg2.chat.id
assert ev.data2 == 0
ac2.direct_imap.idle_check(terminate=True)
lp.step("1")
for i in range(2):

View File

@@ -1795,42 +1795,7 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<(),
)
.await?;
context.emit_event(EventType::MsgsChanged {
chat_id: ChatId::new(0),
msg_id: MsgId::new(0),
});
Ok(())
}
pub async fn marknoticed_all_chats(context: &Context) -> Result<(), Error> {
if !context
.sql
.exists(
"SELECT id
FROM msgs
WHERE state=10;",
paramsv![],
)
.await?
{
return Ok(());
}
context
.sql
.execute(
"UPDATE msgs
SET state=13
WHERE state=10;",
paramsv![],
)
.await?;
context.emit_event(EventType::MsgsChanged {
msg_id: MsgId::new(0),
chat_id: ChatId::new(0),
});
context.emit_event(EventType::MsgsNoticed(chat_id));
Ok(())
}

View File

@@ -16,7 +16,7 @@ use crate::error::{bail, ensure, format_err, Result};
use crate::events::EventType;
use crate::key::{DcKey, SignedPublicKey};
use crate::login_param::LoginParam;
use crate::message::{MessageState, MsgId};
use crate::message::MessageState;
use crate::mimeparser::AvatarAction;
use crate::param::*;
use crate::peerstate::*;
@@ -260,10 +260,9 @@ impl Contact {
Ok(contact_id)
}
/// Mark all messages sent by the given contact
/// as *noticed*. See also dc_marknoticed_chat() and dc_markseen_msgs()
///
/// Calling this function usually results in the event `#DC_EVENT_MSGS_CHANGED`.
/// Mark messages from a contact as noticed.
/// The contact is expected to belong to the deaddrop,
/// therefore, DC_EVENT_MSGS_NOTICED(DC_CHAT_ID_DEADDROP) is emitted.
pub async fn mark_noticed(context: &Context, id: u32) {
if context
.sql
@@ -274,10 +273,7 @@ impl Contact {
.await
.is_ok()
{
context.emit_event(EventType::MsgsChanged {
chat_id: ChatId::new(0),
msg_id: MsgId::new(0),
});
context.emit_event(EventType::MsgsNoticed(ChatId::new(DC_CHAT_ID_DEADDROP)));
}
}

View File

@@ -186,6 +186,11 @@ pub enum EventType {
#[strum(props(id = "2005"))]
IncomingMsg { chat_id: ChatId, msg_id: MsgId },
/// Messages were seen or noticed.
/// chat id is always set.
#[strum(props(id = "2008"))]
MsgsNoticed(ChatId),
/// A single message is sent successfully. State changed from DC_STATE_OUT_PENDING to
/// DC_STATE_OUT_DELIVERED, see dc_msg_get_state().
#[strum(props(id = "2010"))]

View File

@@ -19,6 +19,7 @@ use crate::mimeparser::{FailureReport, SystemMessage};
use crate::param::*;
use crate::pgp::*;
use crate::stock::StockMessage;
use std::collections::BTreeMap;
// In practice, the user additionally cuts the string themselves
// pixel-accurate.
@@ -1226,6 +1227,7 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
.with_conn(move |conn| {
let mut stmt = conn.prepare_cached(concat!(
"SELECT",
" m.chat_id AS chat_id,",
" m.state AS state,",
" c.blocked AS blocked",
" FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id",
@@ -1236,6 +1238,7 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
for id in msg_ids.into_iter() {
let query_res = stmt.query_row(paramsv![id], |row| {
Ok((
row.get::<_, ChatId>("chat_id")?,
row.get::<_, MessageState>("state")?,
row.get::<_, Option<Blocked>>("blocked")?
.unwrap_or_default(),
@@ -1244,8 +1247,8 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
if let Err(rusqlite::Error::QueryReturnedNoRows) = query_res {
continue;
}
let (state, blocked) = query_res.map_err(Into::<anyhow::Error>::into)?;
msgs.push((id, state, blocked));
let (chat_id, state, blocked) = query_res.map_err(Into::<anyhow::Error>::into)?;
msgs.push((id, chat_id, state, blocked));
}
Ok(msgs)
@@ -1253,9 +1256,9 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
.await
.unwrap_or_default();
let mut send_event = false;
let mut updated_chat_ids = BTreeMap::new();
for (id, curr_state, curr_blocked) in msgs.into_iter() {
for (id, curr_chat_id, curr_state, curr_blocked) in msgs.into_iter() {
if let Err(err) = id.start_ephemeral_timer(context).await {
error!(
context,
@@ -1274,19 +1277,16 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
job::Job::new(Action::MarkseenMsgOnImap, id.to_u32(), Params::new(), 0),
)
.await;
send_event = true;
updated_chat_ids.insert(curr_chat_id, true);
}
} else if curr_state == MessageState::InFresh {
update_msg_state(context, id, MessageState::InNoticed).await;
send_event = true;
updated_chat_ids.insert(ChatId::new(DC_CHAT_ID_DEADDROP), true);
}
}
if send_event {
context.emit_event(EventType::MsgsChanged {
chat_id: ChatId::new(0),
msg_id: MsgId::new(0),
});
for updated_chat_id in updated_chat_ids.keys() {
context.emit_event(EventType::MsgsNoticed(*updated_chat_id));
}
true