WIP: api!: add LIMIT arg to get_chat_media

In Delta Chat desktop we show the 3 recently used WebXDC apps,
which relies on `get_chat_media`, which is quite expensive.
Hopefully adding `LIMIT 3` makes it faster.

Marking this as a breaking change
because it's breaking TypeScript-wise,
but shouldn't be breaking behavior-wise,
because not providing the argument in JSON-RPC
should be equivalent to providing `null`
(which gets converted to `None`).

TODO:
- [ ] Add to CFFI?
- [ ] Docs. Both the core fn and the JSON-RPC.
This commit is contained in:
WofWca
2025-10-20 19:05:52 +04:00
parent fc81cef113
commit 781de46e26
5 changed files with 64 additions and 5 deletions

View File

@@ -1532,6 +1532,7 @@ pub unsafe extern "C" fn dc_get_chat_media(
msg_type: libc::c_int,
or_msg_type2: libc::c_int,
or_msg_type3: libc::c_int,
// limit: u32,
) -> *mut dc_array::dc_array_t {
if context.is_null() {
eprintln!("ignoring careless call to dc_get_chat_media()");
@@ -1551,7 +1552,7 @@ pub unsafe extern "C" fn dc_get_chat_media(
block_on(async move {
Box::into_raw(Box::new(
chat::get_chat_media(ctx, chat_id, msg_type, or_msg_type2, or_msg_type3)
chat::get_chat_media(ctx, chat_id, msg_type, or_msg_type2, or_msg_type3, None)
.await
.unwrap_or_log_default(ctx, "Failed get_chat_media")
.into(),

View File

@@ -1734,6 +1734,7 @@ impl CommandApi {
message_type: MessageViewtype,
or_message_type2: Option<MessageViewtype>,
or_message_type3: Option<MessageViewtype>,
limit: Option<u32>,
) -> Result<Vec<u32>> {
let ctx = self.get_context(account_id).await?;
@@ -1745,7 +1746,8 @@ impl CommandApi {
let or_msg_type2 = or_message_type2.map_or(Viewtype::Unknown, |v| v.into());
let or_msg_type3 = or_message_type3.map_or(Viewtype::Unknown, |v| v.into());
let media = get_chat_media(&ctx, chat_id, msg_type, or_msg_type2, or_msg_type3).await?;
let media =
get_chat_media(&ctx, chat_id, msg_type, or_msg_type2, or_msg_type3, limit).await?;
Ok(media.iter().map(|msg_id| msg_id.to_u32()).collect())
}

View File

@@ -1016,6 +1016,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
Viewtype::Image,
Viewtype::Gif,
Viewtype::Video,
None,
)
.await?;
println!("{} images or videos: ", images.len());

View File

@@ -3292,6 +3292,7 @@ pub async fn get_chat_media(
msg_type: Viewtype,
msg_type2: Viewtype,
msg_type3: Viewtype,
limit: Option<u32>,
) -> Result<Vec<MsgId>> {
let list = if msg_type == Viewtype::Webxdc
&& msg_type2 == Viewtype::Unknown
@@ -3306,12 +3307,14 @@ pub async fn get_chat_media(
AND chat_id != ?
AND type = ?
AND hidden=0
ORDER BY max(timestamp, timestamp_rcvd), id;",
ORDER BY max(timestamp, timestamp_rcvd), id
LIMIT ?;",
(
chat_id.is_none(),
chat_id.unwrap_or_else(|| ChatId::new(0)),
DC_CHAT_ID_TRASH,
Viewtype::Webxdc,
limit.map(|l| l.to_string()).unwrap_or("ALL".to_string()),
),
|row| row.get::<_, MsgId>(0),
|ids| Ok(ids.flatten().collect()),
@@ -3327,7 +3330,8 @@ pub async fn get_chat_media(
AND chat_id != ?
AND type IN (?, ?, ?)
AND hidden=0
ORDER BY timestamp, id;",
ORDER BY timestamp, id
LIMIT ?;",
(
chat_id.is_none(),
chat_id.unwrap_or_else(|| ChatId::new(0)),
@@ -3343,6 +3347,7 @@ pub async fn get_chat_media(
} else {
msg_type
},
limit.map(|l| l.to_string()).unwrap_or("ALL".to_string()),
),
|row| row.get::<_, MsgId>(0),
|ids| Ok(ids.flatten().collect()),

View File

@@ -3189,7 +3189,8 @@ async fn test_get_chat_media() -> Result<()> {
Some(chat_id1),
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Unknown
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3250,6 +3251,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Image,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3262,6 +3264,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Sticker,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3274,11 +3277,25 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Sticker,
Viewtype::Image,
Viewtype::Unknown,
None,
)
.await?
.len(),
2
);
assert_eq!(
get_chat_media(
&t,
Some(chat_id1),
Viewtype::Sticker,
Viewtype::Image,
Viewtype::Unknown,
Some(1),
)
.await?
.len(),
1
);
assert_eq!(
get_chat_media(
&t,
@@ -3286,6 +3303,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Webxdc,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3298,6 +3316,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Image,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3310,6 +3329,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Unknown,
None,
)
.await?
.len(),
@@ -3322,6 +3342,33 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Webxdc,
None,
)
.await?
.len(),
4
);
assert_eq!(
get_chat_media(
&t,
None,
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Webxdc,
Some(3),
)
.await?
.len(),
3
);
assert_eq!(
get_chat_media(
&t,
None,
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Webxdc,
Some(99),
)
.await?
.len(),
@@ -3337,6 +3384,7 @@ async fn test_get_chat_media() -> Result<()> {
Viewtype::Image,
Viewtype::Sticker,
Viewtype::Webxdc,
None,
)
.await?
.len(),
@@ -3378,6 +3426,7 @@ async fn test_get_chat_media_webxdc_order() -> Result<()> {
Viewtype::Webxdc,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?;
assert_eq!(media.first().unwrap(), &instance1_id);
@@ -3393,6 +3442,7 @@ async fn test_get_chat_media_webxdc_order() -> Result<()> {
Viewtype::Webxdc,
Viewtype::Unknown,
Viewtype::Unknown,
None,
)
.await?;
assert_eq!(media.first().unwrap(), &instance2_id);