mirror of
https://github.com/chatmail/core.git
synced 2026-05-06 06:46:35 +03:00
move payload to {payload:PAYLOAD} to allow additional parameters
additional parameters will be `summary` and `msg` (for an info-message) right now, and maybe more in the future (`aggregated`, `fast`, `to` ...), so adding just more parameters easily gets wild. also, this makes adaptions easier as no ffi needs to be adapted when we add more parameters. finally, sending is in-sync with receiving, database and wire now, one receives similar objects as one sends, which also looks like the right thing :) for now, `sendUpdate()` also allows to use the old, unwrapped payload to not immediately break existing `.xdc`, however, that will be removed soon, probably before the first release.
This commit is contained in:
@@ -21,13 +21,14 @@ no need to add `webxdc.js` to your ZIP-file):
|
|||||||
### sendUpdate()
|
### sendUpdate()
|
||||||
|
|
||||||
```js
|
```js
|
||||||
window.webxdc.sendUpdate(payload, descr);
|
window.webxdc.sendUpdate(update, descr);
|
||||||
```
|
```
|
||||||
|
|
||||||
Webxdc apps are usually shared in a chat and run independently on each peer.
|
Webxdc apps are usually shared in a chat and run independently on each peer.
|
||||||
To get a shared state, the peers use `sendUpdate()` to send updates to each other.
|
To get a shared state, the peers use `sendUpdate()` to send updates to each other.
|
||||||
|
|
||||||
- `payload`: any javascript primitive, array or object.
|
- `update`: an object with the following fields:
|
||||||
|
`update.payload`: any javascript primitive, array or object.
|
||||||
- `descr`: short, human-readable description what this update is about.
|
- `descr`: short, human-readable description what this update is about.
|
||||||
this is shown eg. as a fallback text in an email program.
|
this is shown eg. as a fallback text in an email program.
|
||||||
|
|
||||||
@@ -43,8 +44,8 @@ window.webxdc.setUpdateListener((update) => {});
|
|||||||
With `setUpdateListener()` you define a callback that receives the updates
|
With `setUpdateListener()` you define a callback that receives the updates
|
||||||
sent by `sendUpdate()`.
|
sent by `sendUpdate()`.
|
||||||
|
|
||||||
- `update`: passed to the callback on updates.
|
- `update`: passed to the callback on updates with the following fields:
|
||||||
- `update.payload`: equals the payload given to `sendUpdate()`
|
`update.payload`: equals the payload given to `sendUpdate()`
|
||||||
|
|
||||||
The callback is called for updates sent by you or other peers.
|
The callback is called for updates sent by you or other peers.
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ The following example shows an input field and every input is show on all peers
|
|||||||
|
|
||||||
function sendMsg() {
|
function sendMsg() {
|
||||||
msg = document.getElementById("input").value;
|
msg = document.getElementById("input").value;
|
||||||
window.webxdc.sendUpdate(msg, 'Someone typed "'+msg+'".');
|
window.webxdc.sendUpdate({payload: msg}, 'Someone typed "'+msg+'".');
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveUpdate(update) {
|
function receiveUpdate(update) {
|
||||||
|
|||||||
@@ -86,19 +86,27 @@ impl Context {
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes a payload and writes it to the database.
|
/// Takes an update-json as `{payload: PAYLOAD}` (or legacy `PAYLOAD`)
|
||||||
|
/// and writes it to the database.
|
||||||
/// Moreover, events are handled.
|
/// Moreover, events are handled.
|
||||||
async fn create_status_update_record(
|
async fn create_status_update_record(
|
||||||
&self,
|
&self,
|
||||||
instance_msg_id: MsgId,
|
instance_msg_id: MsgId,
|
||||||
payload: &str,
|
update_str: &str,
|
||||||
) -> Result<StatusUpdateId> {
|
) -> Result<StatusUpdateId> {
|
||||||
let payload = payload.trim();
|
let update_str = update_str.trim();
|
||||||
if payload.is_empty() {
|
if update_str.is_empty() {
|
||||||
bail!("create_status_update_record: empty payload");
|
bail!("create_status_update_record: empty update.");
|
||||||
}
|
}
|
||||||
let payload: Value = serde_json::from_str(payload)?; // checks if input data are valid json
|
|
||||||
let status_update_item = StatusUpdateItem { payload };
|
let status_update_item: StatusUpdateItem =
|
||||||
|
if let Ok(status_update_item) = serde_json::from_str(update_str) {
|
||||||
|
status_update_item
|
||||||
|
} else {
|
||||||
|
// TODO: this fallback (legacy `PAYLOAD`) should be deleted soon, together with the test below
|
||||||
|
let payload: Value = serde_json::from_str(update_str)?; // checks if input data are valid json
|
||||||
|
StatusUpdateItem { payload }
|
||||||
|
};
|
||||||
|
|
||||||
let rowid = self
|
let rowid = self
|
||||||
.sql
|
.sql
|
||||||
@@ -127,7 +135,7 @@ impl Context {
|
|||||||
pub async fn send_webxdc_status_update(
|
pub async fn send_webxdc_status_update(
|
||||||
&self,
|
&self,
|
||||||
instance_msg_id: MsgId,
|
instance_msg_id: MsgId,
|
||||||
payload: &str,
|
update_str: &str,
|
||||||
descr: &str,
|
descr: &str,
|
||||||
) -> Result<Option<MsgId>> {
|
) -> Result<Option<MsgId>> {
|
||||||
let instance = Message::load_from_db(self, instance_msg_id).await?;
|
let instance = Message::load_from_db(self, instance_msg_id).await?;
|
||||||
@@ -136,7 +144,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let status_update_id = self
|
let status_update_id = self
|
||||||
.create_status_update_record(instance_msg_id, payload)
|
.create_status_update_record(instance_msg_id, update_str)
|
||||||
.await?;
|
.await?;
|
||||||
match instance.state {
|
match instance.state {
|
||||||
MessageState::Undefined | MessageState::OutPreparing | MessageState::OutDraft => {
|
MessageState::Undefined | MessageState::OutPreparing | MessageState::OutDraft => {
|
||||||
@@ -207,11 +215,8 @@ impl Context {
|
|||||||
|
|
||||||
let updates: StatusUpdates = serde_json::from_str(json)?;
|
let updates: StatusUpdates = serde_json::from_str(json)?;
|
||||||
for update_item in updates.updates {
|
for update_item in updates.updates {
|
||||||
self.create_status_update_record(
|
self.create_status_update_record(instance.id, &*serde_json::to_string(&update_item)?)
|
||||||
instance.id,
|
.await?;
|
||||||
&*serde_json::to_string(&update_item.payload)?,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -489,7 +494,7 @@ mod tests {
|
|||||||
.await?;
|
.await?;
|
||||||
chat_id.set_draft(&t, Some(&mut instance)).await?;
|
chat_id.set_draft(&t, Some(&mut instance)).await?;
|
||||||
let instance = chat_id.get_draft(&t).await?.unwrap();
|
let instance = chat_id.get_draft(&t).await?.unwrap();
|
||||||
t.send_webxdc_status_update(instance.id, "42", "descr")
|
t.send_webxdc_status_update(instance.id, r#"{"payload": 42}"#, "descr")
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
t.get_webxdc_status_updates(instance.id, None).await?,
|
t.get_webxdc_status_updates(instance.id, None).await?,
|
||||||
@@ -521,7 +526,7 @@ mod tests {
|
|||||||
assert_eq!(t.get_webxdc_status_updates(instance.id, None).await?, "[]");
|
assert_eq!(t.get_webxdc_status_updates(instance.id, None).await?, "[]");
|
||||||
|
|
||||||
let id = t
|
let id = t
|
||||||
.create_status_update_record(instance.id, "\n\n{\"foo\":\"bar\"}\n")
|
.create_status_update_record(instance.id, "\n\n{\"payload\": {\"foo\":\"bar\"}}\n")
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
||||||
@@ -546,13 +551,14 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let id = t
|
let id = t
|
||||||
.create_status_update_record(instance.id, r#"{"foo2":"bar2"}"#)
|
.create_status_update_record(instance.id, r#"{"payload" : { "foo2":"bar2"}}"#)
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
||||||
r#"[{"payload":{"foo2":"bar2"}}]"#
|
r#"[{"payload":{"foo2":"bar2"}}]"#
|
||||||
);
|
);
|
||||||
t.create_status_update_record(instance.id, "true").await?;
|
t.create_status_update_record(instance.id, r#"{"payload":true}"#)
|
||||||
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
t.get_webxdc_status_updates(instance.id, None).await?,
|
t.get_webxdc_status_updates(instance.id, None).await?,
|
||||||
r#"[{"payload":{"foo":"bar"}},
|
r#"[{"payload":{"foo":"bar"}},
|
||||||
@@ -560,6 +566,26 @@ mod tests {
|
|||||||
{"payload":true}]"#
|
{"payload":true}]"#
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let id = t
|
||||||
|
.create_status_update_record(
|
||||||
|
instance.id,
|
||||||
|
r#"{"payload" : 1, "sender": "that is not used"}"#,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(
|
||||||
|
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
||||||
|
r#"[{"payload":1}]"#
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: legacy `PAYLOAD` support should be deleted soon
|
||||||
|
let id = t
|
||||||
|
.create_status_update_record(instance.id, r#"{"foo" : 1}"#)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(
|
||||||
|
t.get_webxdc_status_updates(instance.id, Some(id)).await?,
|
||||||
|
r#"[{"payload":{"foo":1}}]"#
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,7 +682,11 @@ mod tests {
|
|||||||
assert!(!sent1.payload().contains("report-type=status-update"));
|
assert!(!sent1.payload().contains("report-type=status-update"));
|
||||||
|
|
||||||
let status_update_msg_id = alice
|
let status_update_msg_id = alice
|
||||||
.send_webxdc_status_update(alice_instance.id, r#"{"foo":"bar"}"#, "descr text")
|
.send_webxdc_status_update(
|
||||||
|
alice_instance.id,
|
||||||
|
r#"{"payload" : {"foo":"bar"}}"#,
|
||||||
|
"descr text",
|
||||||
|
)
|
||||||
.await?
|
.await?
|
||||||
.unwrap();
|
.unwrap();
|
||||||
expect_status_update_event(&alice, alice_instance.id).await?;
|
expect_status_update_event(&alice, alice_instance.id).await?;
|
||||||
@@ -682,7 +712,11 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
alice
|
alice
|
||||||
.send_webxdc_status_update(alice_instance.id, r#"{"snipp":"snapp"}"#, "bla text")
|
.send_webxdc_status_update(
|
||||||
|
alice_instance.id,
|
||||||
|
r#"{"payload":{"snipp":"snapp"}}"#,
|
||||||
|
"bla text",
|
||||||
|
)
|
||||||
.await?
|
.await?
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -738,7 +772,8 @@ mod tests {
|
|||||||
.await?
|
.await?
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
t.send_webxdc_status_update(instance.id, "1", "bla").await?;
|
t.send_webxdc_status_update(instance.id, r#"{"payload": 1}"#, "bla")
|
||||||
|
.await?;
|
||||||
assert!(t
|
assert!(t
|
||||||
.render_webxdc_status_update_object(instance.id, None)
|
.render_webxdc_status_update_object(instance.id, None)
|
||||||
.await?
|
.await?
|
||||||
@@ -767,12 +802,12 @@ mod tests {
|
|||||||
let mut alice_instance = alice_chat_id.get_draft(&alice).await?.unwrap();
|
let mut alice_instance = alice_chat_id.get_draft(&alice).await?.unwrap();
|
||||||
|
|
||||||
let status_update_msg_id = alice
|
let status_update_msg_id = alice
|
||||||
.send_webxdc_status_update(alice_instance.id, r#"{"foo":"bar"}"#, "descr")
|
.send_webxdc_status_update(alice_instance.id, r#"{"payload": {"foo":"bar"}}"#, "descr")
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(status_update_msg_id, None);
|
assert_eq!(status_update_msg_id, None);
|
||||||
expect_status_update_event(&alice, alice_instance.id).await?;
|
expect_status_update_event(&alice, alice_instance.id).await?;
|
||||||
let status_update_msg_id = alice
|
let status_update_msg_id = alice
|
||||||
.send_webxdc_status_update(alice_instance.id, r#"42"#, "descr")
|
.send_webxdc_status_update(alice_instance.id, r#"{"payload":42}"#, "descr")
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(status_update_msg_id, None);
|
assert_eq!(status_update_msg_id, None);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user