Skip to content

Commit

Permalink
set_webxdc_integration() takes an .xdc file
Browse files Browse the repository at this point in the history
  • Loading branch information
r10s committed Apr 14, 2024
1 parent cec5409 commit 3198a85
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 68 deletions.
55 changes: 22 additions & 33 deletions deltachat-ffi/deltachat.h
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,17 @@ int dc_send_webxdc_status_update (dc_context_t* context, uint32_t msg_id, const
char* dc_get_webxdc_status_updates (dc_context_t* context, uint32_t msg_id, uint32_t serial);


/**
* Set Webxdc file as integration.
* see dc_init_webxdc_integration() for more details about Webxdc integrations.
*
* @memberof dc_context_t
* @param context The context object.
* @param file The .xdc file to use as Webxdc integration.
*/
void dc_set_webxdc_integration (dc_context_t* context, const char* file);


/**
* Init a Webxdc integration.
*
Expand All @@ -1199,7 +1210,17 @@ char* dc_get_webxdc_status_updates (dc_context_t* context, uint32_t msg_id, uint
* There is no need to de-initialize the integration,
* however, the integration is valid only as long as not re-initialized.
*
* See dc_msg_set_webxdc_integration() for an example.
* Example:
*
* ~~~
* dc_msg_set_webxdc_integration(context, path_to_maps_xdc);
*
* // Later on, you can use dc_init_webxdc_integration() to integrate the map to any chat:
* uint32_t webxdc_instance = dc_init_webxdc_integration(context, any_chat_id);
*
* // Or use it as a global map, showing locations of all chats:
* uint32_t webxdc_instance = dc_init_webxdc_integration(context, 0);
* ~~~
*
* @memberof dc_context_t
* @param context The context object.
Expand Down Expand Up @@ -4709,38 +4730,6 @@ void dc_msg_set_override_sender_name(dc_msg_t* msg, const char* name)
void dc_msg_set_file (dc_msg_t* msg, const char* file, const char* filemime);


/**
* Mark Webxdc message shipped with the main app as a default integration.
* Example:
*
* ~~~
* dc_msg_t* msg = dc_msg_new(context, DC_MSG_WEBXDC);
* dc_msg_set_file(msg, path_to_maps_xdc);
* dc_msg_set_webxdc_integration(msg);
* dc_send_msg(dc_create_chat_by_contact_id(context, DC_CONTACT_ID_SELF), msg);
* ~~~
*
* Later on, you can use dc_init_webxdc_integration() to integrate the map to any chat:
*
* ~~~
* uint32_t webxdc_instance = dc_init_webxdc_integration(context, any_chat_id);
* ~~~
*
* Or use it as a global map, showing locations of all chats:
*
* ~~~
* uint32_t webxdc_instance = dc_init_webxdc_integration(context, 0);
* ~~~
*
* The returned webxdc_instance can be used the same way as any other Webxdc.
* see dc_init_webxdc_integration() for more details about Webxdc integrations.
*
* @memberof dc_msg_t
* @param msg The Webxdc message object to mark as default integration.
*/
void dc_msg_set_webxdc_integration (dc_msg_t* msg);


/**
* Set the dimensions associated with message object.
* Typically this is the width and the height of an image or video associated using dc_msg_set_file().
Expand Down
25 changes: 15 additions & 10 deletions deltachat-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,21 @@ pub unsafe extern "C" fn dc_get_webxdc_status_updates(
.strdup()
}

#[no_mangle]
pub unsafe extern "C" fn dc_msg_set_webxdc_integration(
context: *mut dc_context_t,
file: *const libc::c_char,
) {
if context.is_null() || file.is_null() {
eprintln!("ignoring careless call to dc_msg_set_webxdc_integration()");
return;
}
let ctx = &*context;
block_on(ctx.set_webxdc_integration(to_string_lossy(file)))
.log_err(ctx)
.unwrap_or_default();
}

#[no_mangle]
pub unsafe extern "C" fn dc_init_webxdc_integration(
context: *mut dc_context_t,
Expand Down Expand Up @@ -3757,16 +3772,6 @@ pub unsafe extern "C" fn dc_msg_set_file(
)
}

#[no_mangle]
pub unsafe extern "C" fn dc_msg_set_webxdc_integration(msg: *mut dc_msg_t) {
if msg.is_null() {
eprintln!("ignoring careless call to dc_msg_set_webxdc_integration()");
return;
}
let ffi_msg = &mut *msg;
ffi_msg.message.set_webxdc_integration()
}

#[no_mangle]
pub unsafe extern "C" fn dc_msg_set_dimension(
msg: *mut dc_msg_t,
Expand Down
32 changes: 16 additions & 16 deletions src/webxdc/integration.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use crate::chat::ChatId;
use crate::chat::{send_msg, ChatId};
use crate::config::Config;
use crate::contact::ContactId;
use crate::context::Context;
use crate::message::{Message, MsgId, Viewtype};
use crate::param::Param;
use crate::webxdc::{maps_integration, StatusUpdateItem, StatusUpdateSerial};
use anyhow::Result;

impl Message {
/// Mark Webxdc message shipped with the main app as a default integration.
pub fn set_webxdc_integration(&mut self) {
self.hidden = true;
self.param.set_int(Param::WebxdcIntegration, 1);
impl Context {
/// Set Webxdc file as integration.
pub async fn set_webxdc_integration(&self, file: String) -> Result<()> {
let chat_id = ChatId::create_for_contact(self, ContactId::SELF).await?;
let mut msg = Message::new(Viewtype::Webxdc);
msg.set_file(file.as_str(), None);
msg.hidden = true;
msg.param.set_int(Param::WebxdcIntegration, 1);
send_msg(self, chat_id, &mut msg).await?;
Ok(())
}
}

impl Context {
/// Get Webxdc instance used for optional integrations.
/// If there is no integration, the caller may decide to add a default one.
pub async fn init_webxdc_integration(
Expand Down Expand Up @@ -45,7 +49,7 @@ impl Context {
.set_int(Param::WebxdcIntegrateFor, integrate_for);
instance.update_param(self).await?;
}
return Ok(Some(instance.id));
Ok(Some(instance.id))
}

// Check if a Webxdc shall be used as an integration and remember that.
Expand Down Expand Up @@ -99,9 +103,7 @@ impl Context {

#[cfg(test)]
mod tests {
use crate::chat::send_msg;
use crate::config::Config;
use crate::message::{Message, Viewtype};
use crate::test_utils::TestContext;
use anyhow::Result;
use std::time::Duration;
Expand All @@ -110,14 +112,12 @@ mod tests {
async fn test_default_integrations_are_single_device() -> Result<()> {
let t = TestContext::new_alice().await;
t.set_config_bool(Config::BccSelf, false).await?;
let chat = t.get_self_chat().await;

let bytes = include_bytes!("../../test-data/webxdc/minimal.xdc");
let mut msg = Message::new(Viewtype::Webxdc);
msg.set_file_from_bytes(&t, "my-maps.xdc", bytes, None)
let file = t.get_blobdir().join("maps.xdc");
tokio::fs::write(&file, bytes).await.unwrap();
t.set_webxdc_integration(file.to_str().unwrap().to_string())
.await?;
msg.set_webxdc_integration();
send_msg(&t, chat.id, &mut msg).await?;

// default integrations are shipped with the apps and should not be sent over the wire
let sent = t.pop_sent_msg_opt(Duration::from_secs(1)).await;
Expand Down
13 changes: 4 additions & 9 deletions src/webxdc/maps_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,31 +171,26 @@ pub(crate) async fn intercept_get_updates(

#[cfg(test)]
mod tests {
use crate::chat::{create_group_chat, send_msg, ChatId, ProtectionStatus};
use crate::chat::{create_group_chat, ChatId, ProtectionStatus};
use crate::chatlist::Chatlist;
use crate::contact::Contact;
use crate::location;
use crate::message::{Message, Viewtype};
use crate::test_utils::TestContext;
use crate::webxdc::StatusUpdateSerial;
use anyhow::Result;

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_maps_integration() -> Result<()> {
let t = TestContext::new_alice().await;
let chat = t.get_self_chat().await;

let bytes = include_bytes!("../../test-data/webxdc/minimal.xdc");
let mut msg = Message::new(Viewtype::Webxdc);
msg.set_file_from_bytes(&t, "my-maps.xdc", bytes, None)
let file = t.get_blobdir().join("maps.xdc");
tokio::fs::write(&file, bytes).await.unwrap();
t.set_webxdc_integration(file.to_str().unwrap().to_string())
.await?;
msg.set_webxdc_integration();
let msg_id = send_msg(&t, chat.id, &mut msg).await?;

let msg = Message::load_from_db(&t, msg_id).await?;
let chatlist = Chatlist::try_load(&t, 0, None, None).await?;
let summary = chatlist.get_summary(&t, 0, None).await?;
assert!(msg.hidden);
assert_eq!(summary.text, "No messages.");

// Integrate Webxdc into a chat with Bob;
Expand Down

0 comments on commit 3198a85

Please sign in to comment.