mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 04:46:29 +03:00
feat: experimental Webxdc Integration API, Maps Integration (#5461)
as discussed in several chats, this PR starts making it possible to use Webxdc as integrations to the main app. In other word: selected parts of the main app can be integrated as Webxdc, eg. Maps [^1] this PR contains two parts: - draft an Webxdc Integration API - use the Webxdc Integration API to create a Maps Integration to be clear: a Webxdc is not part of this PR. the PR is about marking a Webxdc being used as a Map - and core then feeds the Webxdc with location data. from the view of the Webxdc, the normal `sendUpdate()`/`setUpdateListener()` is used. things are still marked as "experimental", idea is to get that in to allow @adbenitez and @nicodh to move forward on the integrations into android and desktop, as well as improving the maps.xdc itself. good news is that we currently can change the protocol between Webxdc and core at any point :) # Webxdc Integration API see `dc_init_webxdc_integration()` in `deltachat.h` for overview and documentation. rust code is mostly in `webxdc/integration.rs` that is called by other places as needed. current [user of the API is deltachat-ios](https://github.com/deltachat/deltachat-ios/pull/1912), android/desktop will probably follow. the jsonrpc part is missing and can come in another PR when things are settled and desktop is really starting [^2] (so we won't need to do all iterations twice :) makes also sense, when this is done by someone actually trying that out on desktop while the API is prepared to allow other types of integrations (photo editor, compose tools ...) internally, we currently ignore the type. if that gets more crazy, we probably also need a dedicated table for the integrations and not just a single param. # Maps Integration rust code is mostly in `webxdc/maps_integration.rs` that is called by `webxdc/integration.rs` as needed. EDIT: the idea of having a split here, is that `webxdc/maps_integration.rs` really can focus on the json part, on the communication with the .xdc, including tests this PR is basic implementation, enabling to move forward on integrations on iOS, but also on desktop and android. the current implementation allows already the following: - global and per-chat maps - add and display POIs - show positions and tracks of the last 24 hours the current maps.xdc uses leaflet, and is in some regards better than the current android/desktop implementations (much faster, show age of positions, fade out positions, always show names of POIs, clearer UI). however, we are also not bound to leaflet, it can be anything > [**screenshots of the current state**](https://github.com/deltachat/deltachat-ios/pull/1912) > 👆 to move forward faster and to keep this PR small, the following will go to a subsequent PR: - consider allowing webxdc to use a different timewindow for the location - delete POIs - jsonrpc [^1]: maps are a good example as anyways barely native (see android app), did cause a lot of pain on many levels in the past (technically, bureaucratically), and have a comparable simple api [^2]: only going for jsonrpc would only make sense if large parts of android/ios would use jsonrpc, we're not there --------- Co-authored-by: link2xt <link2xt@testrun.org>
This commit is contained in:
@@ -1178,6 +1178,65 @@ 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.
|
||||
*
|
||||
* @warning This is an experimental API which may change in the future
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* A Webxdc integration is
|
||||
* a Webxdc showing a map, getting locations via setUpdateListener(), setting POIs via sendUpdate();
|
||||
* core takes eg. care of feeding locations to the Webxdc or sending the data out.
|
||||
*
|
||||
* @warning This is an experimental API, esp. support of integration types (eg. image editor, tools) is left out for simplicity
|
||||
*
|
||||
* Currently, Webxdc integrations are .xdc files shipped together with the main app.
|
||||
* Before dc_init_webxdc_integration() can be called,
|
||||
* UI has to call dc_set_webxdc_integration() to define a .xdc file to be used as integration.
|
||||
*
|
||||
* dc_init_webxdc_integration() returns a Webxdc message ID that
|
||||
* UI can open and use mostly as usual.
|
||||
*
|
||||
* Concrete behaviour and status updates depend on the integration, driven by UI needs.
|
||||
*
|
||||
* There is no need to de-initialize the integration,
|
||||
* however, unless documented otherwise,
|
||||
* the integration is valid only as long as not re-initialized
|
||||
* In other words, UI must not have a Webxdc with the same integration open twice.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ~~~
|
||||
* // Define a .xdc file to be used as maps integration
|
||||
* dc_set_webxdc_integration(context, path_to_maps_xdc);
|
||||
*
|
||||
* // Integrate the map to a chat, the map will show locations for this chat then:
|
||||
* uint32_t webxdc_instance = dc_init_webxdc_integration(context, any_chat_id);
|
||||
*
|
||||
* // Or use the Webxdc 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.
|
||||
* @param chat_id The chat to get the integration for.
|
||||
* @return ID of the message that refers to the Webxdc instance.
|
||||
* UI can open a Webxdc as usual with this instance.
|
||||
*/
|
||||
uint32_t dc_init_webxdc_integration (dc_context_t* context, uint32_t chat_id);
|
||||
|
||||
|
||||
/**
|
||||
* Save a draft for a chat in the database.
|
||||
*
|
||||
@@ -4107,7 +4166,6 @@ char* dc_msg_get_webxdc_blob (const dc_msg_t* msg, const char*
|
||||
* true if the Webxdc should get full internet access, including Webrtc.
|
||||
* currently, this is only true for encrypted Webxdc's in the self chat
|
||||
* that have requested internet access in the manifest.
|
||||
* this is useful for development and maybe for internal integrations at some point.
|
||||
*
|
||||
* @memberof dc_msg_t
|
||||
* @param msg The webxdc instance.
|
||||
|
||||
@@ -1063,6 +1063,43 @@ pub unsafe extern "C" fn dc_get_webxdc_status_updates(
|
||||
.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_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_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,
|
||||
chat_id: u32,
|
||||
) -> u32 {
|
||||
if context.is_null() {
|
||||
eprintln!("ignoring careless call to dc_init_webxdc_integration()");
|
||||
return 0;
|
||||
}
|
||||
let ctx = &*context;
|
||||
let chat_id = if chat_id == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(ChatId::new(chat_id))
|
||||
};
|
||||
|
||||
block_on(ctx.init_webxdc_integration(chat_id))
|
||||
.log_err(ctx)
|
||||
.map(|msg_id| msg_id.map(|id| id.to_u32()).unwrap_or_default())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_set_draft(
|
||||
context: *mut dc_context_t,
|
||||
|
||||
Reference in New Issue
Block a user