mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
4 Commits
acffad37ef
...
link2xt/ge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97465bd0e6 | ||
|
|
751edd4772 | ||
|
|
d22f62005c | ||
|
|
f02888e3cc |
@@ -6,6 +6,7 @@
|
||||
|
||||
### API-Changes
|
||||
- Add Python API to send reactions #3762
|
||||
- Add API to get next fresh message #3777
|
||||
|
||||
### Fixes
|
||||
- Make sure malformed messsages will never block receiving further messages anymore #3771
|
||||
|
||||
@@ -1278,6 +1278,18 @@ int dc_estimate_deletion_cnt (dc_context_t* context, int from_ser
|
||||
dc_array_t* dc_get_fresh_msgs (dc_context_t* context);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ID of the fresh message of any chat.
|
||||
*
|
||||
* If there is no such message, the function blocks until there is one.
|
||||
*
|
||||
* @memberof dc_context_t
|
||||
* @param context The context object as returned from dc_context_new().
|
||||
* @return Message ID of the next fresh message. Returns 0 on error.
|
||||
*/
|
||||
dc_array_t* dc_get_next_fresh_msg (dc_context_t* context);
|
||||
|
||||
|
||||
/**
|
||||
* Mark all messages in a chat as _noticed_.
|
||||
* _Noticed_ messages are no longer _fresh_ and do not count as being unseen
|
||||
|
||||
@@ -1243,6 +1243,20 @@ pub unsafe extern "C" fn dc_get_fresh_msgs(
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_get_next_fresh_msg(context: *mut dc_context_t) -> u32 {
|
||||
if context.is_null() {
|
||||
eprintln!("ignoring careless call to dc_get_next_fresh_msg()");
|
||||
return 0;
|
||||
}
|
||||
let ctx = &*context;
|
||||
|
||||
block_on(ctx.get_next_fresh_msg())
|
||||
.log_err(ctx, "Failed to get next fresh message")
|
||||
.unwrap_or_default()
|
||||
.to_u32()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_marknoticed_chat(context: *mut dc_context_t, chat_id: u32) {
|
||||
if context.is_null() {
|
||||
|
||||
@@ -372,6 +372,15 @@ impl CommandApi {
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Returns the message ID of the oldest fresh message.
|
||||
///
|
||||
/// If there are no such messages, waits until there is one.
|
||||
async fn get_next_fresh_msg(&self, account_id: u32) -> Result<u32> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
let msg_id = ctx.get_next_fresh_msg().await?;
|
||||
Ok(msg_id.to_u32())
|
||||
}
|
||||
|
||||
/// Get the number of _fresh_ messages in a chat.
|
||||
/// Typically used to implement a badge with a number in the chatlist.
|
||||
///
|
||||
|
||||
@@ -371,6 +371,11 @@ class Account(object):
|
||||
dc_array = ffi.gc(lib.dc_get_fresh_msgs(self._dc_context), lib.dc_array_unref)
|
||||
yield from iter_array(dc_array, lambda x: Message.from_db(self, x))
|
||||
|
||||
def get_next_fresh_message(self) -> Message:
|
||||
"""Returns the oldest fresh message or waits for a new one to arrive."""
|
||||
msg_id = lib.dc_get_next_fresh_msg(self._dc_context)
|
||||
return Message.from_db(self, msg_id)
|
||||
|
||||
def create_chat(self, obj) -> Chat:
|
||||
"""Create a 1:1 chat with Account, Contact or e-mail address."""
|
||||
return self.create_contact(obj).create_chat()
|
||||
|
||||
@@ -710,6 +710,7 @@ def test_send_and_receive_will_encrypt_decrypt(acfactory, lp):
|
||||
fresh_msgs = list(ac1.get_fresh_messages())
|
||||
assert len(fresh_msgs) == 1
|
||||
assert fresh_msgs[0] == msg3
|
||||
assert ac1.get_next_fresh_message() == msg3
|
||||
msg3.mark_seen()
|
||||
assert not list(ac1.get_fresh_messages())
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::time::{Duration, Instant, SystemTime};
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
use async_channel::{self as channel, Receiver, Sender};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::sync::{Mutex, Notify, RwLock};
|
||||
|
||||
use crate::chat::{get_chat_cnt, ChatId};
|
||||
use crate::config::Config;
|
||||
@@ -205,6 +205,11 @@ pub struct InnerContext {
|
||||
pub(crate) translated_stockstrings: StockStrings,
|
||||
pub(crate) events: Events,
|
||||
|
||||
/// Notify about fresh messages.
|
||||
///
|
||||
/// This notification is used only internally for [`InternalContext.get_next_fresh_msg()`].
|
||||
pub(crate) notify_fresh_message: Notify,
|
||||
|
||||
pub(crate) scheduler: RwLock<Option<Scheduler>>,
|
||||
pub(crate) ratelimit: RwLock<Ratelimit>,
|
||||
|
||||
@@ -354,6 +359,7 @@ impl Context {
|
||||
wrong_pw_warning_mutex: Mutex::new(()),
|
||||
translated_stockstrings: stockstrings,
|
||||
events,
|
||||
notify_fresh_message: Notify::new(),
|
||||
scheduler: RwLock::new(None),
|
||||
ratelimit: RwLock::new(Ratelimit::new(Duration::new(60, 0), 6.0)), // Allow to send 6 messages immediately, no more than once every 10 seconds.
|
||||
quota: RwLock::new(None),
|
||||
@@ -451,9 +457,12 @@ impl Context {
|
||||
self.emit_event(EventType::MsgsChanged { chat_id, msg_id });
|
||||
}
|
||||
|
||||
/// Emits an IncomingMsg event with specified chat and message ids
|
||||
/// Emits an IncomingMsg event with specified chat and message ids.
|
||||
///
|
||||
/// Notifies `get_next_fresh_msg()` that there might be a new fresh message.
|
||||
pub fn emit_incoming_msg(&self, chat_id: ChatId, msg_id: MsgId) {
|
||||
self.emit_event(EventType::IncomingMsg { chat_id, msg_id });
|
||||
self.notify_fresh_message.notify_one();
|
||||
}
|
||||
|
||||
/// Returns a receiver for emitted events.
|
||||
@@ -751,6 +760,19 @@ impl Context {
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
/// Returns oldest fresh message in unmuted and unblocked chats.
|
||||
///
|
||||
/// If there are no such messages, waits until there is one.
|
||||
pub async fn get_next_fresh_msg(&self) -> Result<MsgId> {
|
||||
loop {
|
||||
if let Some(msg_id) = self.get_fresh_msgs().await?.last() {
|
||||
return Ok(*msg_id);
|
||||
} else {
|
||||
self.notify_fresh_message.notified().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Searches for messages containing the query string.
|
||||
///
|
||||
/// If `chat_id` is provided this searches only for messages in this chat, if `chat_id`
|
||||
|
||||
Reference in New Issue
Block a user