-
-
Notifications
You must be signed in to change notification settings - Fork 100
add a device-chat #794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add a device-chat #794
Changes from all commits
8017c12
8b6b9ec
5380a96
024f034
15031f1
ba1e79f
8733d66
7791f77
c614550
01ae2bb
13d12a7
b59c421
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,6 +97,8 @@ impl Chat { | |
|
||
if chat.param.exists(Param::Selftalk) { | ||
chat.name = context.stock_str(StockMessage::SelfMsg).into(); | ||
} else if chat.param.exists(Param::Devicetalk) { | ||
chat.name = context.stock_str(StockMessage::DeviceMessages).into(); | ||
} | ||
} | ||
} | ||
|
@@ -109,6 +111,14 @@ impl Chat { | |
self.param.exists(Param::Selftalk) | ||
} | ||
|
||
pub fn is_device_talk(&self) -> bool { | ||
self.param.exists(Param::Devicetalk) | ||
} | ||
|
||
pub fn can_send(&self) -> bool { | ||
self.id > DC_CHAT_ID_LAST_SPECIAL && !self.is_device_talk() | ||
} | ||
|
||
pub fn update_param(&mut self, context: &Context) -> Result<(), Error> { | ||
sql::execute( | ||
context, | ||
|
@@ -582,6 +592,12 @@ pub fn set_blocking(context: &Context, chat_id: u32, new_blocking: Blocked) -> b | |
.is_ok() | ||
} | ||
|
||
fn copy_device_icon_to_blobs(context: &Context) -> Result<String, Error> { | ||
let icon = include_bytes!("../assets/icon-device.png"); | ||
let blob = BlobObject::create(context, "icon-device.png".to_string(), icon)?; | ||
Ok(blob.as_name().to_string()) | ||
} | ||
|
||
pub fn create_or_lookup_by_contact_id( | ||
context: &Context, | ||
contact_id: u32, | ||
|
@@ -605,7 +621,14 @@ pub fn create_or_lookup_by_contact_id( | |
"INSERT INTO chats (type, name, param, blocked, grpid) VALUES({}, '{}', '{}', {}, '{}')", | ||
100, | ||
chat_name, | ||
if contact_id == DC_CONTACT_ID_SELF as u32 { "K=1" } else { "" }, | ||
match contact_id { | ||
DC_CONTACT_ID_SELF => "K=1".to_string(), // K = Param::Selftalk | ||
DC_CONTACT_ID_DEVICE => { | ||
let icon = copy_device_icon_to_blobs(context)?; | ||
format!("D=1\ni={}", icon) // D = Param::Devicetalk, i = Param::ProfileImage | ||
}, | ||
_ => "".to_string() | ||
}, | ||
create_blocked as u8, | ||
contact.get_addr(), | ||
), | ||
|
@@ -677,8 +700,7 @@ pub fn msgtype_has_file(msgtype: Viewtype) -> bool { | |
} | ||
} | ||
|
||
fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Result<MsgId, Error> { | ||
msg.id = MsgId::new_unset(); | ||
fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<(), Error> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a nice refactor |
||
if msg.type_0 == Viewtype::Text { | ||
// the caller should check if the message text is empty | ||
} else if msgtype_has_file(msg.type_0) { | ||
|
@@ -714,10 +736,16 @@ fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Res | |
} else { | ||
bail!("Cannot send messages of type #{}.", msg.type_0); | ||
} | ||
Ok(()) | ||
} | ||
|
||
fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Result<MsgId, Error> { | ||
msg.id = MsgId::new_unset(); | ||
prepare_msg_blob(context, msg)?; | ||
unarchive(context, chat_id)?; | ||
|
||
let mut chat = Chat::load_from_db(context, chat_id)?; | ||
ensure!(chat.can_send(), "cannot send to chat #{}", chat_id); | ||
|
||
// The OutPreparing state is set by dc_prepare_msg() before it | ||
// calls this function and the message is left in the OutPreparing | ||
|
@@ -994,7 +1022,7 @@ pub fn get_chat_msgs( | |
" LEFT JOIN contacts", | ||
" ON m.from_id=contacts.id", | ||
" WHERE m.from_id!=1", // 1=DC_CONTACT_ID_SELF | ||
" AND m.from_id!=2", // 2=DC_CONTACT_ID_DEVICE | ||
" AND m.from_id!=2", // 2=DC_CONTACT_ID_INFO | ||
" AND m.hidden=0", | ||
" AND chats.blocked=2", | ||
" AND contacts.blocked=0", | ||
|
@@ -1898,15 +1926,46 @@ pub fn get_chat_id_by_grpid(context: &Context, grpid: impl AsRef<str>) -> (u32, | |
.unwrap_or((0, false, Blocked::Not)) | ||
} | ||
|
||
pub fn add_device_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) { | ||
pub fn add_device_msg(context: &Context, msg: &mut Message) -> Result<MsgId, Error> { | ||
let (chat_id, _blocked) = | ||
create_or_lookup_by_contact_id(context, DC_CONTACT_ID_DEVICE, Blocked::Not)?; | ||
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device"); | ||
|
||
prepare_msg_blob(context, msg)?; | ||
unarchive(context, chat_id)?; | ||
|
||
context.sql.execute( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this a custom insert? I appreciate you don't want to call send_msg() but i'm surprised to see a whole new sql query. I probably missed something though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is just no other but i think this is no issue. these sqls are easy enough and so it is pretty clear what happens. |
||
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,param,rfc724_mid) \ | ||
VALUES (?,?,?, ?,?,?, ?,?,?);", | ||
params![ | ||
chat_id, | ||
DC_CONTACT_ID_DEVICE, | ||
DC_CONTACT_ID_SELF, | ||
dc_create_smeared_timestamp(context), | ||
msg.type_0, | ||
MessageState::InFresh, | ||
msg.text.as_ref().map_or("", String::as_str), | ||
msg.param.to_string(), | ||
rfc724_mid, | ||
], | ||
)?; | ||
|
||
let row_id = sql::get_rowid(context, &context.sql, "msgs", "rfc724_mid", &rfc724_mid); | ||
let msg_id = MsgId::new(row_id); | ||
context.call_cb(Event::IncomingMsg { chat_id, msg_id }); | ||
|
||
Ok(msg_id) | ||
} | ||
|
||
pub fn add_info_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) { | ||
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device"); | ||
|
||
if context.sql.execute( | ||
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid) VALUES (?,?,?, ?,?,?, ?,?);", | ||
params![ | ||
chat_id as i32, | ||
DC_CONTACT_ID_DEVICE, | ||
DC_CONTACT_ID_DEVICE, | ||
DC_CONTACT_ID_INFO, | ||
DC_CONTACT_ID_INFO, | ||
dc_create_smeared_timestamp(context), | ||
Viewtype::Text, | ||
MessageState::InNoticed, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a
libc::??
return type?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, i did just a copy+paste from dc_chat_can_send() :)
i leave it for now, maybe we can go trough the ffi and streamline this at some point for all affected functions.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libc::uint32_t
is deprecated in favor ofu32
in Rust. And usingu32
is better thanlibc::c_uint
because JNI and NAPI don't work these C types anyway.Keep it returning
u32
and specify it asuint32_t
in C API.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are going to streamline it, I would rather change all ints to int32_t, because it is equal to int32_t on all existing architectures anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for explaining, @link2xt