mirror of
https://github.com/chatmail/core.git
synced 2026-05-13 11:56:30 +03:00
allow webxdc document names (#3317)
* allow webxdc document names * test document webxdc property * update CHANGELOG
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
- send normal messages with higher priority than MDNs #3243
|
- send normal messages with higher priority than MDNs #3243
|
||||||
- make Scheduler stateless #3302
|
- make Scheduler stateless #3302
|
||||||
- support `source_code_url` from Webxdc manifests #3314
|
- support `source_code_url` from Webxdc manifests #3314
|
||||||
|
- support Webxdc document names and add `document` to `dc_msg_get_webxdc_info()` #3317
|
||||||
- improve chat encryption info, make it easier to find contacts without keys #3318
|
- improve chat encryption info, make it easier to find contacts without keys #3318
|
||||||
|
|
||||||
### API-Changes
|
### API-Changes
|
||||||
|
|||||||
@@ -3728,6 +3728,8 @@ char* dc_msg_get_webxdc_blob (const dc_msg_t* msg, const char*
|
|||||||
* To get the file, use dc_msg_get_webxdc_blob().
|
* To get the file, use dc_msg_get_webxdc_blob().
|
||||||
* App icons should should be square,
|
* App icons should should be square,
|
||||||
* the implementations will add round corners etc. as needed.
|
* the implementations will add round corners etc. as needed.
|
||||||
|
* - document: if the Webxdc represents a document, this is the name of the document,
|
||||||
|
* otherwise, this is an empty string.
|
||||||
* - summary: short string describing the state of the app,
|
* - summary: short string describing the state of the app,
|
||||||
* sth. as "2 votes", "Highscore: 123",
|
* sth. as "2 votes", "Highscore: 123",
|
||||||
* can be changed by the apps and defaults to an empty string.
|
* can be changed by the apps and defaults to an empty string.
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ To get a shared state, the peers use `sendUpdate()` to send updates to each othe
|
|||||||
eg. "Alice voted" or "Bob scored 123 in MyGame";
|
eg. "Alice voted" or "Bob scored 123 in MyGame";
|
||||||
usually only one line of text is shown,
|
usually only one line of text is shown,
|
||||||
use this option sparingly to not spam the chat.
|
use this option sparingly to not spam the chat.
|
||||||
|
- `update.document`: optional, name of the document in edit,
|
||||||
|
must not be used eg. in games where the Webxdc does not create documents
|
||||||
- `update.summary`: optional, short text, shown beside app icon;
|
- `update.summary`: optional, short text, shown beside app icon;
|
||||||
it is recommended to use some aggregated value, eg. "8 votes", "Highscore: 123"
|
it is recommended to use some aggregated value, eg. "8 votes", "Highscore: 123"
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,12 @@ pub enum Param {
|
|||||||
/// For Chats: timestamp of protection settings update.
|
/// For Chats: timestamp of protection settings update.
|
||||||
ProtectionSettingsTimestamp = b'L',
|
ProtectionSettingsTimestamp = b'L',
|
||||||
|
|
||||||
|
/// For Webxdc Message Instances: Current document name
|
||||||
|
WebxdcDocument = b'R',
|
||||||
|
|
||||||
|
/// For Webxdc Message Instances: timestamp of document name update.
|
||||||
|
WebxdcDocumentTimestamp = b'W',
|
||||||
|
|
||||||
/// For Webxdc Message Instances: Current summary
|
/// For Webxdc Message Instances: Current summary
|
||||||
WebxdcSummary = b'N',
|
WebxdcSummary = b'N',
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ struct WebxdcManifest {
|
|||||||
pub struct WebxdcInfo {
|
pub struct WebxdcInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub icon: String,
|
pub icon: String,
|
||||||
|
pub document: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
pub source_code_url: String,
|
pub source_code_url: String,
|
||||||
}
|
}
|
||||||
@@ -116,6 +117,9 @@ pub(crate) struct StatusUpdateItem {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
info: Option<String>,
|
info: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
document: Option<String>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
summary: Option<String>,
|
summary: Option<String>,
|
||||||
}
|
}
|
||||||
@@ -191,8 +195,8 @@ impl Context {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes an update-json as `{payload: PAYLOAD}` (or legacy `PAYLOAD`)
|
/// Takes an update-json as `{payload: PAYLOAD}`
|
||||||
/// writes it to the database and handles events, info-messages and summary.
|
/// writes it to the database and handles events, info-messages, document name and summary.
|
||||||
async fn create_status_update_record(
|
async fn create_status_update_record(
|
||||||
&self,
|
&self,
|
||||||
instance: &mut Message,
|
instance: &mut Message,
|
||||||
@@ -212,6 +216,7 @@ impl Context {
|
|||||||
| MessageState::OutDraft => StatusUpdateItem {
|
| MessageState::OutDraft => StatusUpdateItem {
|
||||||
payload: item.payload,
|
payload: item.payload,
|
||||||
info: None, // no info-messages in draft mode
|
info: None, // no info-messages in draft mode
|
||||||
|
document: item.document,
|
||||||
summary: item.summary,
|
summary: item.summary,
|
||||||
},
|
},
|
||||||
_ => item,
|
_ => item,
|
||||||
@@ -234,17 +239,33 @@ impl Context {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut param_changed = false;
|
||||||
|
|
||||||
|
if let Some(ref document) = status_update_item.document {
|
||||||
|
if instance
|
||||||
|
.param
|
||||||
|
.update_timestamp(Param::WebxdcDocumentTimestamp, timestamp)?
|
||||||
|
{
|
||||||
|
instance.param.set(Param::WebxdcDocument, document);
|
||||||
|
param_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ref summary) = status_update_item.summary {
|
if let Some(ref summary) = status_update_item.summary {
|
||||||
if instance
|
if instance
|
||||||
.param
|
.param
|
||||||
.update_timestamp(Param::WebxdcSummaryTimestamp, timestamp)?
|
.update_timestamp(Param::WebxdcSummaryTimestamp, timestamp)?
|
||||||
{
|
{
|
||||||
instance.param.set(Param::WebxdcSummary, summary);
|
instance.param.set(Param::WebxdcSummary, summary);
|
||||||
instance.update_param(self).await;
|
param_changed = true;
|
||||||
self.emit_msgs_changed(instance.chat_id, instance.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if param_changed {
|
||||||
|
instance.update_param(self).await;
|
||||||
|
self.emit_msgs_changed(instance.chat_id, instance.id);
|
||||||
|
}
|
||||||
|
|
||||||
let rowid = self
|
let rowid = self
|
||||||
.sql
|
.sql
|
||||||
.insert(
|
.insert(
|
||||||
@@ -572,6 +593,11 @@ impl Message {
|
|||||||
} else {
|
} else {
|
||||||
WEBXDC_DEFAULT_ICON.to_string()
|
WEBXDC_DEFAULT_ICON.to_string()
|
||||||
},
|
},
|
||||||
|
document: self
|
||||||
|
.param
|
||||||
|
.get(Param::WebxdcDocument)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string(),
|
||||||
summary: self
|
summary: self
|
||||||
.param
|
.param
|
||||||
.get(Param::WebxdcSummary)
|
.get(Param::WebxdcSummary)
|
||||||
@@ -1536,6 +1562,48 @@ sth_for_the = "future""#
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_webxdc_document_name() -> Result<()> {
|
||||||
|
let alice = TestContext::new_alice().await;
|
||||||
|
let bob = TestContext::new_bob().await;
|
||||||
|
|
||||||
|
// Alice creates an webxdc instance and updates document name
|
||||||
|
let alice_chat = alice.create_chat(&bob).await;
|
||||||
|
let alice_instance = send_webxdc_instance(&alice, alice_chat.id).await?;
|
||||||
|
let sent_instance = &alice.pop_sent_msg().await;
|
||||||
|
let info = alice_instance.get_webxdc_info(&alice).await?;
|
||||||
|
assert_eq!(info.document, "".to_string());
|
||||||
|
assert_eq!(info.summary, "".to_string());
|
||||||
|
|
||||||
|
alice
|
||||||
|
.send_webxdc_status_update(
|
||||||
|
alice_instance.id,
|
||||||
|
r#"{"document":"my file", "payload":1337}"#,
|
||||||
|
"descr",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let sent_update1 = &alice.pop_sent_msg().await;
|
||||||
|
let info = Message::load_from_db(&alice, alice_instance.id)
|
||||||
|
.await?
|
||||||
|
.get_webxdc_info(&alice)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(info.document, "my file".to_string());
|
||||||
|
assert_eq!(info.summary, "".to_string());
|
||||||
|
|
||||||
|
// Bob receives the updates
|
||||||
|
bob.recv_msg(sent_instance).await;
|
||||||
|
let bob_instance = bob.get_last_msg().await;
|
||||||
|
bob.recv_msg(sent_update1).await;
|
||||||
|
let info = Message::load_from_db(&bob, bob_instance.id)
|
||||||
|
.await?
|
||||||
|
.get_webxdc_info(&bob)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(info.document, "my file".to_string());
|
||||||
|
assert_eq!(info.summary, "".to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[async_std::test]
|
#[async_std::test]
|
||||||
async fn test_webxdc_info_msg() -> Result<()> {
|
async fn test_webxdc_info_msg() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let alice = TestContext::new_alice().await;
|
||||||
|
|||||||
Reference in New Issue
Block a user