mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
refactor(chat): rust based memory management
This commit is contained in:
@@ -570,7 +570,10 @@ pub unsafe extern "C" fn dc_get_chat<'a>(
|
|||||||
assert!(!context.is_null());
|
assert!(!context.is_null());
|
||||||
let context = &*context;
|
let context = &*context;
|
||||||
|
|
||||||
chat::dc_get_chat(context, chat_id)
|
match chat::dc_get_chat(context, chat_id) {
|
||||||
|
Ok(chat) => Box::into_raw(Box::new(chat)),
|
||||||
|
Err(_) => std::ptr::null_mut(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -1239,7 +1242,9 @@ pub unsafe extern "C" fn dc_chatlist_get_summary<'a>(
|
|||||||
) -> *mut dc_lot::dc_lot_t {
|
) -> *mut dc_lot::dc_lot_t {
|
||||||
assert!(!chatlist.is_null());
|
assert!(!chatlist.is_null());
|
||||||
|
|
||||||
|
let chat = if chat.is_null() { None } else { Some(&*chat) };
|
||||||
let list = &*chatlist;
|
let list = &*chatlist;
|
||||||
|
|
||||||
list.get_summary(index as usize, chat)
|
list.get_summary(index as usize, chat)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,12 +1267,13 @@ pub type dc_chat_t<'a> = chat::Chat<'a>;
|
|||||||
pub unsafe extern "C" fn dc_chat_unref(chat: *mut dc_chat_t) {
|
pub unsafe extern "C" fn dc_chat_unref(chat: *mut dc_chat_t) {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
|
||||||
chat::dc_chat_unref(chat)
|
Box::from_raw(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_id(chat: *mut dc_chat_t) -> u32 {
|
pub unsafe extern "C" fn dc_chat_get_id(chat: *mut dc_chat_t) -> u32 {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_id(chat)
|
chat::dc_chat_get_id(chat)
|
||||||
}
|
}
|
||||||
@@ -1275,6 +1281,7 @@ pub unsafe extern "C" fn dc_chat_get_id(chat: *mut dc_chat_t) -> u32 {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_type(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_get_type(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_type(chat) as libc::c_int
|
chat::dc_chat_get_type(chat) as libc::c_int
|
||||||
}
|
}
|
||||||
@@ -1282,6 +1289,7 @@ pub unsafe extern "C" fn dc_chat_get_type(chat: *mut dc_chat_t) -> libc::c_int {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_name(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
pub unsafe extern "C" fn dc_chat_get_name(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_name(chat)
|
chat::dc_chat_get_name(chat)
|
||||||
}
|
}
|
||||||
@@ -1289,6 +1297,7 @@ pub unsafe extern "C" fn dc_chat_get_name(chat: *mut dc_chat_t) -> *mut libc::c_
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_subtitle(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
pub unsafe extern "C" fn dc_chat_get_subtitle(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_subtitle(chat)
|
chat::dc_chat_get_subtitle(chat)
|
||||||
}
|
}
|
||||||
@@ -1296,6 +1305,7 @@ pub unsafe extern "C" fn dc_chat_get_subtitle(chat: *mut dc_chat_t) -> *mut libc
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_profile_image(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
pub unsafe extern "C" fn dc_chat_get_profile_image(chat: *mut dc_chat_t) -> *mut libc::c_char {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_profile_image(chat)
|
chat::dc_chat_get_profile_image(chat)
|
||||||
}
|
}
|
||||||
@@ -1303,6 +1313,7 @@ pub unsafe extern "C" fn dc_chat_get_profile_image(chat: *mut dc_chat_t) -> *mut
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_color(chat: *mut dc_chat_t) -> u32 {
|
pub unsafe extern "C" fn dc_chat_get_color(chat: *mut dc_chat_t) -> u32 {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_color(chat)
|
chat::dc_chat_get_color(chat)
|
||||||
}
|
}
|
||||||
@@ -1310,6 +1321,7 @@ pub unsafe extern "C" fn dc_chat_get_color(chat: *mut dc_chat_t) -> u32 {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_get_archived(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_get_archived(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_get_archived(chat) as libc::c_int
|
chat::dc_chat_get_archived(chat) as libc::c_int
|
||||||
}
|
}
|
||||||
@@ -1317,6 +1329,7 @@ pub unsafe extern "C" fn dc_chat_get_archived(chat: *mut dc_chat_t) -> libc::c_i
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_is_unpromoted(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_is_unpromoted(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_is_unpromoted(chat)
|
chat::dc_chat_is_unpromoted(chat)
|
||||||
}
|
}
|
||||||
@@ -1324,6 +1337,7 @@ pub unsafe extern "C" fn dc_chat_is_unpromoted(chat: *mut dc_chat_t) -> libc::c_
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_is_self_talk(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_is_self_talk(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_is_self_talk(chat)
|
chat::dc_chat_is_self_talk(chat)
|
||||||
}
|
}
|
||||||
@@ -1331,6 +1345,7 @@ pub unsafe extern "C" fn dc_chat_is_self_talk(chat: *mut dc_chat_t) -> libc::c_i
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_is_verified(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_is_verified(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_is_verified(chat)
|
chat::dc_chat_is_verified(chat)
|
||||||
}
|
}
|
||||||
@@ -1338,6 +1353,7 @@ pub unsafe extern "C" fn dc_chat_is_verified(chat: *mut dc_chat_t) -> libc::c_in
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_chat_is_sending_locations(chat: *mut dc_chat_t) -> libc::c_int {
|
pub unsafe extern "C" fn dc_chat_is_sending_locations(chat: *mut dc_chat_t) -> libc::c_int {
|
||||||
assert!(!chat.is_null());
|
assert!(!chat.is_null());
|
||||||
|
let chat = &*chat;
|
||||||
|
|
||||||
chat::dc_chat_is_sending_locations(chat) as libc::c_int
|
chat::dc_chat_is_sending_locations(chat) as libc::c_int
|
||||||
}
|
}
|
||||||
@@ -1500,6 +1516,7 @@ pub unsafe extern "C" fn dc_msg_get_summary<'a>(
|
|||||||
chat: *mut dc_chat_t<'a>,
|
chat: *mut dc_chat_t<'a>,
|
||||||
) -> *mut dc_lot::dc_lot_t {
|
) -> *mut dc_lot::dc_lot_t {
|
||||||
assert!(!msg.is_null());
|
assert!(!msg.is_null());
|
||||||
|
let chat = if chat.is_null() { None } else { Some(&*chat) };
|
||||||
|
|
||||||
dc_msg::dc_msg_get_summary(msg, chat)
|
dc_msg::dc_msg_get_summary(msg, chat)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,16 +349,16 @@ pub unsafe fn dc_cmdline_skip_auth() {
|
|||||||
S_IS_AUTH = 1;
|
S_IS_AUTH = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn chat_prefix(chat: *const Chat) -> &'static str {
|
fn chat_prefix(chat: &Chat) -> &'static str {
|
||||||
(*chat).typ.into()
|
chat.typ.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> {
|
pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> {
|
||||||
let chat_id = *context.cmdline_sel_chat_id.read().unwrap();
|
let chat_id = *context.cmdline_sel_chat_id.read().unwrap();
|
||||||
let mut sel_chat = if chat_id > 0 {
|
let mut sel_chat = if chat_id > 0 {
|
||||||
dc_get_chat(context, chat_id)
|
dc_get_chat(context, chat_id).ok()
|
||||||
} else {
|
} else {
|
||||||
std::ptr::null_mut()
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut args = line.splitn(3, ' ');
|
let mut args = line.splitn(3, ' ');
|
||||||
@@ -606,23 +606,23 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
);
|
);
|
||||||
|
|
||||||
for i in (0..cnt).rev() {
|
for i in (0..cnt).rev() {
|
||||||
let chat = dc_get_chat(context, chatlist.get_chat_id(i));
|
let chat = dc_get_chat(context, chatlist.get_chat_id(i))?;
|
||||||
let temp_subtitle = dc_chat_get_subtitle(chat);
|
let temp_subtitle = dc_chat_get_subtitle(&chat);
|
||||||
let temp_name = dc_chat_get_name(chat);
|
let temp_name = dc_chat_get_name(&chat);
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
"{}#{}: {} [{}] [{} fresh]",
|
"{}#{}: {} [{}] [{} fresh]",
|
||||||
chat_prefix(chat),
|
chat_prefix(&chat),
|
||||||
dc_chat_get_id(chat) as libc::c_int,
|
dc_chat_get_id(&chat) as libc::c_int,
|
||||||
as_str(temp_name),
|
as_str(temp_name),
|
||||||
as_str(temp_subtitle),
|
as_str(temp_subtitle),
|
||||||
dc_get_fresh_msg_cnt(context, dc_chat_get_id(chat)) as libc::c_int,
|
dc_get_fresh_msg_cnt(context, dc_chat_get_id(&chat)) as libc::c_int,
|
||||||
);
|
);
|
||||||
free(temp_subtitle as *mut libc::c_void);
|
free(temp_subtitle as *mut libc::c_void);
|
||||||
free(temp_name as *mut libc::c_void);
|
free(temp_name as *mut libc::c_void);
|
||||||
let lot = chatlist.get_summary(i, chat);
|
let lot = chatlist.get_summary(i, Some(&chat));
|
||||||
let statestr = if dc_chat_get_archived(chat) {
|
let statestr = if dc_chat_get_archived(&chat) {
|
||||||
" [Archived]"
|
" [Archived]"
|
||||||
} else {
|
} else {
|
||||||
match dc_lot_get_state(lot) {
|
match dc_lot_get_state(lot) {
|
||||||
@@ -645,7 +645,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
to_string(text2),
|
to_string(text2),
|
||||||
statestr,
|
statestr,
|
||||||
×tr,
|
×tr,
|
||||||
if dc_chat_is_sending_locations(chat) {
|
if dc_chat_is_sending_locations(&chat) {
|
||||||
"📍"
|
"📍"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
@@ -654,7 +654,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
free(text1 as *mut libc::c_void);
|
free(text1 as *mut libc::c_void);
|
||||||
free(text2 as *mut libc::c_void);
|
free(text2 as *mut libc::c_void);
|
||||||
dc_lot_unref(lot);
|
dc_lot_unref(lot);
|
||||||
dc_chat_unref(chat);
|
|
||||||
info!(
|
info!(
|
||||||
context, 0,
|
context, 0,
|
||||||
"================================================================================"
|
"================================================================================"
|
||||||
@@ -667,20 +666,18 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
println!("{} chats", cnt);
|
println!("{} chats", cnt);
|
||||||
}
|
}
|
||||||
"chat" => {
|
"chat" => {
|
||||||
if sel_chat.is_null() && arg1.is_empty() {
|
if sel_chat.is_none() && arg1.is_empty() {
|
||||||
bail!("Argument [chat-id] is missing.");
|
bail!("Argument [chat-id] is missing.");
|
||||||
}
|
}
|
||||||
if !sel_chat.is_null() && !arg1.is_empty() {
|
|
||||||
dc_chat_unref(sel_chat);
|
|
||||||
}
|
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let chat_id = arg1.parse()?;
|
let chat_id = arg1.parse()?;
|
||||||
println!("Selecting chat #{}", chat_id);
|
println!("Selecting chat #{}", chat_id);
|
||||||
sel_chat = dc_get_chat(context, chat_id);
|
sel_chat = Some(dc_get_chat(context, chat_id)?);
|
||||||
*context.cmdline_sel_chat_id.write().unwrap() = chat_id;
|
*context.cmdline_sel_chat_id.write().unwrap() = chat_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure!(!sel_chat.is_null(), "Failed to select chat");
|
ensure!(sel_chat.is_some(), "Failed to select chat");
|
||||||
|
let sel_chat = sel_chat.as_ref().unwrap();
|
||||||
|
|
||||||
let msglist = dc_get_chat_msgs(context, dc_chat_get_id(sel_chat), 0x1, 0);
|
let msglist = dc_get_chat_msgs(context, dc_chat_get_id(sel_chat), 0x1, 0);
|
||||||
let temp2 = dc_chat_get_subtitle(sel_chat);
|
let temp2 = dc_chat_get_subtitle(sel_chat);
|
||||||
@@ -730,16 +727,10 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
"createchatbymsg" => {
|
"createchatbymsg" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <msg-id> missing");
|
ensure!(!arg1.is_empty(), "Argument <msg-id> missing");
|
||||||
let msg_id_0: libc::c_int = arg1.parse()?;
|
let msg_id_0: libc::c_int = arg1.parse()?;
|
||||||
let chat_id_0: libc::c_int =
|
let chat_id_0 = dc_create_chat_by_msg_id(context, msg_id_0 as uint32_t) as libc::c_int;
|
||||||
dc_create_chat_by_msg_id(context, msg_id_0 as uint32_t) as libc::c_int;
|
|
||||||
if chat_id_0 != 0 {
|
if chat_id_0 != 0 {
|
||||||
let chat_0: *mut Chat = dc_get_chat(context, chat_id_0 as uint32_t);
|
let chat = dc_get_chat(context, chat_id_0 as uint32_t)?;
|
||||||
println!(
|
println!("{}#{} created successfully.", chat_prefix(&chat), chat_id_0,);
|
||||||
"{}#{} created successfully.",
|
|
||||||
chat_prefix(chat_0),
|
|
||||||
chat_id_0,
|
|
||||||
);
|
|
||||||
dc_chat_unref(chat_0);
|
|
||||||
} else {
|
} else {
|
||||||
bail!("");
|
bail!("");
|
||||||
}
|
}
|
||||||
@@ -763,13 +754,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"addmember" => {
|
"addmember" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected");
|
ensure!(sel_chat.is_some(), "No chat selected");
|
||||||
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
|
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
|
||||||
|
|
||||||
let contact_id_0: libc::c_int = arg1.parse()?;
|
let contact_id_0: libc::c_int = arg1.parse()?;
|
||||||
if 0 != dc_add_contact_to_chat(
|
if 0 != dc_add_contact_to_chat(
|
||||||
context,
|
context,
|
||||||
dc_chat_get_id(sel_chat),
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
contact_id_0 as uint32_t,
|
contact_id_0 as uint32_t,
|
||||||
) {
|
) {
|
||||||
println!("Contact added to chat.");
|
println!("Contact added to chat.");
|
||||||
@@ -778,12 +769,12 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"removemember" => {
|
"removemember" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
|
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
|
||||||
let contact_id_1: libc::c_int = arg1.parse()?;
|
let contact_id_1: libc::c_int = arg1.parse()?;
|
||||||
if 0 != dc_remove_contact_from_chat(
|
if 0 != dc_remove_contact_from_chat(
|
||||||
context,
|
context,
|
||||||
dc_chat_get_id(sel_chat),
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
contact_id_1 as uint32_t,
|
contact_id_1 as uint32_t,
|
||||||
) {
|
) {
|
||||||
println!("Contact added to chat.");
|
println!("Contact added to chat.");
|
||||||
@@ -792,21 +783,21 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"groupname" => {
|
"groupname" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty(), "Argument <name> missing.");
|
ensure!(!arg1.is_empty(), "Argument <name> missing.");
|
||||||
if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat), arg1_c) {
|
if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat.as_ref().unwrap()), arg1_c) {
|
||||||
println!("Chat name set");
|
println!("Chat name set");
|
||||||
} else {
|
} else {
|
||||||
bail!("Failed to set chat name");
|
bail!("Failed to set chat name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"groupimage" => {
|
"groupimage" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty(), "Argument <image> missing.");
|
ensure!(!arg1.is_empty(), "Argument <image> missing.");
|
||||||
|
|
||||||
if 0 != dc_set_chat_profile_image(
|
if 0 != dc_set_chat_profile_image(
|
||||||
context,
|
context,
|
||||||
dc_chat_get_id(sel_chat),
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
arg1_c
|
arg1_c
|
||||||
} else {
|
} else {
|
||||||
@@ -819,21 +810,33 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"chatinfo" => {
|
"chatinfo" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
|
|
||||||
let contacts = dc_get_chat_contacts(context, dc_chat_get_id(sel_chat));
|
let contacts =
|
||||||
|
dc_get_chat_contacts(context, dc_chat_get_id(sel_chat.as_ref().unwrap()));
|
||||||
info!(context, 0, "Memberlist:");
|
info!(context, 0, "Memberlist:");
|
||||||
|
|
||||||
log_contactlist(context, &contacts);
|
log_contactlist(context, &contacts);
|
||||||
println!(
|
println!(
|
||||||
"{} contacts\nLocation streaming: {}",
|
"{} contacts\nLocation streaming: {}",
|
||||||
contacts.len(),
|
contacts.len(),
|
||||||
dc_is_sending_locations_to_chat(context, dc_chat_get_id(sel_chat)),
|
dc_is_sending_locations_to_chat(
|
||||||
|
context,
|
||||||
|
dc_chat_get_id(sel_chat.as_ref().unwrap())
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"getlocations" => {
|
"getlocations" => {
|
||||||
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
|
|
||||||
let contact_id = arg1.parse().unwrap_or_default();
|
let contact_id = arg1.parse().unwrap_or_default();
|
||||||
let locations = dc_get_locations(context, dc_chat_get_id(sel_chat), contact_id, 0, 0);
|
let locations = dc_get_locations(
|
||||||
|
context,
|
||||||
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
|
contact_id,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
let default_marker = "-".to_string();
|
let default_marker = "-".to_string();
|
||||||
for location in &locations {
|
for location in &locations {
|
||||||
let marker = location.marker.as_ref().unwrap_or(&default_marker);
|
let marker = location.marker.as_ref().unwrap_or(&default_marker);
|
||||||
@@ -857,12 +860,16 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"sendlocations" => {
|
"sendlocations" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty(), "No timeout given.");
|
ensure!(!arg1.is_empty(), "No timeout given.");
|
||||||
|
|
||||||
let seconds = arg1.parse()?;
|
let seconds = arg1.parse()?;
|
||||||
dc_send_locations_to_chat(context, dc_chat_get_id(sel_chat), seconds);
|
dc_send_locations_to_chat(context, dc_chat_get_id(sel_chat.as_ref().unwrap()), seconds);
|
||||||
println!("Locations will be sent to Chat#{} for {} seconds. Use 'setlocation <lat> <lng>' to play around.", dc_chat_get_id(sel_chat), seconds);
|
println!(
|
||||||
|
"Locations will be sent to Chat#{} for {} seconds. Use 'setlocation <lat> <lng>' to play around.",
|
||||||
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
|
seconds
|
||||||
|
);
|
||||||
}
|
}
|
||||||
"setlocation" => {
|
"setlocation" => {
|
||||||
ensure!(
|
ensure!(
|
||||||
@@ -883,27 +890,31 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
dc_delete_all_locations(context);
|
dc_delete_all_locations(context);
|
||||||
}
|
}
|
||||||
"send" => {
|
"send" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty(), "No message text given.");
|
ensure!(!arg1.is_empty(), "No message text given.");
|
||||||
|
|
||||||
let msg = format!("{} {}", arg1, arg2);
|
let msg = format!("{} {}", arg1, arg2);
|
||||||
|
|
||||||
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg) {
|
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat.as_ref().unwrap()), msg) {
|
||||||
println!("Message sent.");
|
println!("Message sent.");
|
||||||
} else {
|
} else {
|
||||||
bail!("Sending failed.");
|
bail!("Sending failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"sendempty" => {
|
"sendempty" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), "".into()) {
|
if 0 != dc_send_text_msg(
|
||||||
|
context,
|
||||||
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
|
"".into(),
|
||||||
|
) {
|
||||||
println!("Message sent.");
|
println!("Message sent.");
|
||||||
} else {
|
} else {
|
||||||
bail!("Sending failed.");
|
bail!("Sending failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"sendimage" | "sendfile" => {
|
"sendimage" | "sendfile" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given.");
|
ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given.");
|
||||||
|
|
||||||
let msg_0 = dc_msg_new(
|
let msg_0 = dc_msg_new(
|
||||||
@@ -916,13 +927,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
);
|
);
|
||||||
dc_msg_set_file(msg_0, arg1_c, 0 as *const libc::c_char);
|
dc_msg_set_file(msg_0, arg1_c, 0 as *const libc::c_char);
|
||||||
dc_msg_set_text(msg_0, arg2_c);
|
dc_msg_set_text(msg_0, arg2_c);
|
||||||
dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0);
|
dc_send_msg(context, dc_chat_get_id(sel_chat.as_ref().unwrap()), msg_0);
|
||||||
dc_msg_unref(msg_0);
|
dc_msg_unref(msg_0);
|
||||||
}
|
}
|
||||||
"listmsgs" => {
|
"listmsgs" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <query> missing.");
|
ensure!(!arg1.is_empty(), "Argument <query> missing.");
|
||||||
|
|
||||||
let chat = if !sel_chat.is_null() {
|
let chat = if let Some(ref sel_chat) = sel_chat {
|
||||||
dc_chat_get_id(sel_chat)
|
dc_chat_get_id(sel_chat)
|
||||||
} else {
|
} else {
|
||||||
0 as libc::c_uint
|
0 as libc::c_uint
|
||||||
@@ -937,25 +948,29 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"draft" => {
|
"draft" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
|
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let draft_0 = dc_msg_new(context, Viewtype::Text);
|
let draft_0 = dc_msg_new(context, Viewtype::Text);
|
||||||
dc_msg_set_text(draft_0, arg1_c);
|
dc_msg_set_text(draft_0, arg1_c);
|
||||||
dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0);
|
dc_set_draft(context, dc_chat_get_id(sel_chat.as_ref().unwrap()), draft_0);
|
||||||
dc_msg_unref(draft_0);
|
dc_msg_unref(draft_0);
|
||||||
println!("Draft saved.");
|
println!("Draft saved.");
|
||||||
} else {
|
} else {
|
||||||
dc_set_draft(context, dc_chat_get_id(sel_chat), 0 as *mut dc_msg_t);
|
dc_set_draft(
|
||||||
|
context,
|
||||||
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
|
0 as *mut dc_msg_t,
|
||||||
|
);
|
||||||
println!("Draft deleted.");
|
println!("Draft deleted.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"listmedia" => {
|
"listmedia" => {
|
||||||
ensure!(!sel_chat.is_null(), "No chat selected.");
|
ensure!(sel_chat.is_some(), "No chat selected.");
|
||||||
|
|
||||||
let images = dc_get_chat_media(
|
let images = dc_get_chat_media(
|
||||||
context,
|
context,
|
||||||
dc_chat_get_id(sel_chat),
|
dc_chat_get_id(sel_chat.as_ref().unwrap()),
|
||||||
Viewtype::Image,
|
Viewtype::Image,
|
||||||
Viewtype::Gif,
|
Viewtype::Gif,
|
||||||
Viewtype::Video,
|
Viewtype::Video,
|
||||||
@@ -1076,9 +1091,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
if 0 != i {
|
if 0 != i {
|
||||||
res += ", ";
|
res += ", ";
|
||||||
}
|
}
|
||||||
let chat = dc_get_chat(context, chatlist.get_chat_id(i));
|
let chat = dc_get_chat(context, chatlist.get_chat_id(i))?;
|
||||||
res += &format!("{}#{}", chat_prefix(chat), dc_chat_get_id(chat));
|
res += &format!("{}#{}", chat_prefix(&chat), dc_chat_get_id(&chat));
|
||||||
dc_chat_unref(chat);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1124,10 +1138,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
_ => bail!("Unknown command: \"{}\" type ? for help.", arg0),
|
_ => bail!("Unknown command: \"{}\" type ? for help.", arg0),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sel_chat.is_null() {
|
|
||||||
dc_chat_unref(sel_chat);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(arg1_c as *mut _);
|
free(arg1_c as *mut _);
|
||||||
free(arg2_c as *mut _);
|
free(arg2_c as *mut _);
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ fn main() {
|
|||||||
let chats = Chatlist::try_load(&ctx, 0, None, None).unwrap();
|
let chats = Chatlist::try_load(&ctx, 0, None, None).unwrap();
|
||||||
|
|
||||||
for i in 0..chats.len() {
|
for i in 0..chats.len() {
|
||||||
let summary = chats.get_summary(0, std::ptr::null_mut());
|
let summary = chats.get_summary(0, None);
|
||||||
let text1 = dc_lot_get_text1(summary);
|
let text1 = dc_lot_get_text1(summary);
|
||||||
let text2 = dc_lot_get_text2(summary);
|
let text2 = dc_lot_get_text2(summary);
|
||||||
|
|
||||||
|
|||||||
471
src/chat.rs
471
src/chat.rs
@@ -8,6 +8,7 @@ use crate::dc_array::*;
|
|||||||
use crate::dc_job::*;
|
use crate::dc_job::*;
|
||||||
use crate::dc_msg::*;
|
use crate::dc_msg::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::param::*;
|
use crate::param::*;
|
||||||
use crate::sql::{self, Sql};
|
use crate::sql::{self, Sql};
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
@@ -21,11 +22,11 @@ use std::ptr;
|
|||||||
/// if you want an update, you have to recreate the object.
|
/// if you want an update, you have to recreate the object.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Chat<'a> {
|
pub struct Chat<'a> {
|
||||||
|
pub context: &'a Context,
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub typ: Chattype,
|
pub typ: Chattype,
|
||||||
pub name: *mut libc::c_char,
|
pub name: *mut libc::c_char,
|
||||||
archived: bool,
|
archived: bool,
|
||||||
pub context: &'a Context,
|
|
||||||
pub grpid: *mut libc::c_char,
|
pub grpid: *mut libc::c_char,
|
||||||
blocked: Blocked,
|
blocked: Blocked,
|
||||||
pub param: Params,
|
pub param: Params,
|
||||||
@@ -33,70 +34,56 @@ pub struct Chat<'a> {
|
|||||||
is_sending_locations: bool,
|
is_sending_locations: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle chats
|
impl<'a> Chat<'a> {
|
||||||
pub unsafe fn dc_create_chat_by_msg_id(context: &Context, msg_id: u32) -> u32 {
|
pub fn new(context: &'a Context) -> Self {
|
||||||
let mut chat_id: u32 = 0i32 as u32;
|
Chat {
|
||||||
let mut send_event: libc::c_int = 0i32;
|
context,
|
||||||
let msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
|
||||||
let chat: *mut Chat = dc_chat_new(context);
|
|
||||||
if dc_msg_load_from_db(msg, context, msg_id)
|
|
||||||
&& dc_chat_load_from_db(chat, (*msg).chat_id)
|
|
||||||
&& (*chat).id > 9i32 as libc::c_uint
|
|
||||||
{
|
|
||||||
chat_id = (*chat).id;
|
|
||||||
if (*chat).blocked != Blocked::Not {
|
|
||||||
dc_unblock_chat(context, (*chat).id);
|
|
||||||
send_event = 1i32
|
|
||||||
}
|
|
||||||
Contact::scaleup_origin_by_id(context, (*msg).from_id, Origin::CreateChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
dc_msg_unref(msg);
|
|
||||||
dc_chat_unref(chat);
|
|
||||||
if 0 != send_event {
|
|
||||||
context.call_cb(Event::MSGS_CHANGED, 0i32 as uintptr_t, 0i32 as uintptr_t);
|
|
||||||
}
|
|
||||||
chat_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn dc_chat_new<'a>(context: &'a Context) -> *mut Chat<'a> {
|
|
||||||
let chat = Chat {
|
|
||||||
id: 0,
|
id: 0,
|
||||||
typ: Chattype::Undefined,
|
typ: Chattype::Undefined,
|
||||||
name: std::ptr::null_mut(),
|
name: std::ptr::null_mut(),
|
||||||
archived: false,
|
archived: false,
|
||||||
context,
|
|
||||||
grpid: std::ptr::null_mut(),
|
grpid: std::ptr::null_mut(),
|
||||||
blocked: Blocked::Not,
|
blocked: Blocked::Not,
|
||||||
param: Params::new(),
|
param: Params::new(),
|
||||||
gossiped_timestamp: 0,
|
gossiped_timestamp: 0,
|
||||||
is_sending_locations: false,
|
is_sending_locations: false,
|
||||||
};
|
}
|
||||||
|
}
|
||||||
Box::into_raw(Box::new(chat))
|
}
|
||||||
|
impl<'a> Drop for Chat<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
free(self.name.cast());
|
||||||
|
free(self.grpid.cast());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_unref(chat: *mut Chat) {
|
// handle chats
|
||||||
if chat.is_null() {
|
pub unsafe fn dc_create_chat_by_msg_id(context: &Context, msg_id: u32) -> u32 {
|
||||||
return;
|
let mut chat_id: u32 = 0i32 as u32;
|
||||||
|
let mut send_event: libc::c_int = 0i32;
|
||||||
|
let msg = dc_msg_new_untyped(context);
|
||||||
|
|
||||||
|
if dc_msg_load_from_db(msg, context, msg_id) {
|
||||||
|
if let Ok(chat) = dc_chat_load_from_db(context, (*msg).chat_id) {
|
||||||
|
if chat.id > 9 {
|
||||||
|
chat_id = chat.id;
|
||||||
|
if chat.blocked != Blocked::Not {
|
||||||
|
dc_unblock_chat(context, chat.id);
|
||||||
|
send_event = 1;
|
||||||
|
}
|
||||||
|
Contact::scaleup_origin_by_id(context, (*msg).from_id, Origin::CreateChat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dc_chat_empty(chat);
|
|
||||||
Box::from_raw(chat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn dc_chat_empty(mut chat: *mut Chat) {
|
dc_msg_unref(msg);
|
||||||
if chat.is_null() {
|
|
||||||
return;
|
if 0 != send_event {
|
||||||
|
context.call_cb(Event::MSGS_CHANGED, 0i32 as uintptr_t, 0i32 as uintptr_t);
|
||||||
}
|
}
|
||||||
free((*chat).name as *mut libc::c_void);
|
chat_id
|
||||||
(*chat).name = ptr::null_mut();
|
|
||||||
(*chat).typ = Chattype::Undefined;
|
|
||||||
(*chat).id = 0i32 as u32;
|
|
||||||
free((*chat).grpid as *mut libc::c_void);
|
|
||||||
(*chat).grpid = ptr::null_mut();
|
|
||||||
(*chat).blocked = Blocked::Not;
|
|
||||||
(*chat).gossiped_timestamp = 0;
|
|
||||||
(*chat).param = Params::new();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_unblock_chat(context: &Context, chat_id: u32) {
|
pub unsafe fn dc_unblock_chat(context: &Context, chat_id: u32) {
|
||||||
@@ -113,21 +100,14 @@ fn dc_block_chat(context: &Context, chat_id: u32, new_blocking: libc::c_int) ->
|
|||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
pub fn dc_chat_load_from_db(context: &Context, chat_id: u32) -> Result<Chat, Error> {
|
||||||
if chat.is_null() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
unsafe { dc_chat_empty(chat) };
|
|
||||||
|
|
||||||
let context = unsafe { (*chat).context };
|
|
||||||
|
|
||||||
let res = context.sql.query_row(
|
let res = context.sql.query_row(
|
||||||
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
||||||
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
||||||
FROM chats c WHERE c.id=?;",
|
FROM chats c WHERE c.id=?;",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
|row| {
|
|row| {
|
||||||
let c = unsafe { &mut *chat };
|
let mut c = Chat::new(context);
|
||||||
|
|
||||||
c.id = row.get(0)?;
|
c.id = row.get(0)?;
|
||||||
c.typ = row.get(1)?;
|
c.typ = row.get(1)?;
|
||||||
@@ -140,68 +120,63 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
|||||||
c.gossiped_timestamp = row.get(7)?;
|
c.gossiped_timestamp = row.get(7)?;
|
||||||
c.is_sending_locations = row.get(8)?;
|
c.is_sending_locations = row.get(8)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(c)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Err(crate::error::Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => false,
|
Err(err @ crate::error::Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => Err(err),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
_ => {
|
_ => {
|
||||||
error!(
|
error!(
|
||||||
context,
|
context,
|
||||||
0, "chat: failed to load from db {}: {:?}", chat_id, err
|
0, "chat: failed to load from db {}: {:?}", chat_id, err
|
||||||
);
|
);
|
||||||
false
|
Err(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Ok(_) => {
|
Ok(mut chat) => {
|
||||||
let c = unsafe { &mut *chat };
|
match chat.id {
|
||||||
match c.id {
|
|
||||||
1 => unsafe {
|
1 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free(chat.name.cast());
|
||||||
(*chat).name = (*chat).context.stock_str(StockMessage::DeadDrop).strdup();
|
chat.name = chat.context.stock_str(StockMessage::DeadDrop).strdup();
|
||||||
},
|
},
|
||||||
6 => unsafe {
|
6 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free(chat.name.cast());
|
||||||
let tempname = (*chat).context.stock_str(StockMessage::ArchivedChats);
|
let tempname = chat.context.stock_str(StockMessage::ArchivedChats);
|
||||||
let cnt = dc_get_archived_cnt((*chat).context);
|
let cnt = dc_get_archived_cnt(chat.context);
|
||||||
(*chat).name = format!("{} ({})", tempname, cnt).strdup();
|
chat.name = format!("{} ({})", tempname, cnt).strdup();
|
||||||
},
|
},
|
||||||
5 => unsafe {
|
5 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free(chat.name.cast());
|
||||||
(*chat).name = (*chat)
|
chat.name = chat.context.stock_str(StockMessage::StarredMsgs).strdup();
|
||||||
.context
|
|
||||||
.stock_str(StockMessage::StarredMsgs)
|
|
||||||
.strdup();
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
unsafe {
|
unsafe {
|
||||||
if (*chat).typ == Chattype::Single {
|
if chat.typ == Chattype::Single {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free(chat.name.cast());
|
||||||
let contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
|
let contacts = dc_get_chat_contacts(chat.context, chat.id);
|
||||||
let mut chat_name = "Err [Name not found]".to_owned();
|
let mut chat_name = "Err [Name not found]".to_owned();
|
||||||
|
|
||||||
if !(*contacts).is_empty() {
|
if !(*contacts).is_empty() {
|
||||||
if let Ok(contact) =
|
if let Ok(contact) = Contact::get_by_id(chat.context, contacts[0]) {
|
||||||
Contact::get_by_id((*chat).context, contacts[0])
|
|
||||||
{
|
|
||||||
chat_name = contact.get_display_name().to_owned();
|
chat_name = contact.get_display_name().to_owned();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*chat).name = (&chat_name).strdup();
|
|
||||||
|
chat.name = (&chat_name).strdup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if unsafe { &(*chat).param }.exists(Param::Selftalk) {
|
if chat.param.exists(Param::Selftalk) {
|
||||||
unsafe {
|
unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free(chat.name as *mut libc::c_void);
|
||||||
(*chat).name =
|
chat.name = chat.context.stock_str(StockMessage::SelfMsg).strdup();
|
||||||
(*chat).context.stock_str(StockMessage::SelfMsg).strdup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
Ok(chat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,15 +433,18 @@ unsafe fn prepare_msg_common<'a>(
|
|||||||
}
|
}
|
||||||
if OK_TO_CONTINUE {
|
if OK_TO_CONTINUE {
|
||||||
dc_unarchive_chat(context, chat_id);
|
dc_unarchive_chat(context, chat_id);
|
||||||
let chat = dc_chat_new(context);
|
if let Ok(mut chat) = dc_chat_load_from_db(context, chat_id) {
|
||||||
if dc_chat_load_from_db(chat, chat_id) {
|
|
||||||
if (*msg).state != DC_STATE_OUT_PREPARING {
|
if (*msg).state != DC_STATE_OUT_PREPARING {
|
||||||
(*msg).state = DC_STATE_OUT_PENDING
|
(*msg).state = DC_STATE_OUT_PENDING
|
||||||
}
|
}
|
||||||
(*msg).id = prepare_msg_raw(context, chat, msg, dc_create_smeared_timestamp(context));
|
(*msg).id = prepare_msg_raw(
|
||||||
|
context,
|
||||||
|
&mut chat,
|
||||||
|
msg,
|
||||||
|
dc_create_smeared_timestamp(context),
|
||||||
|
);
|
||||||
(*msg).chat_id = chat_id
|
(*msg).chat_id = chat_id
|
||||||
}
|
}
|
||||||
dc_chat_unref(chat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*msg).id
|
(*msg).id
|
||||||
@@ -475,7 +453,7 @@ unsafe fn prepare_msg_common<'a>(
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe fn prepare_msg_raw(
|
unsafe fn prepare_msg_raw(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
chat: *mut Chat,
|
chat: &mut Chat,
|
||||||
msg: *mut dc_msg_t,
|
msg: *mut dc_msg_t,
|
||||||
timestamp: i64,
|
timestamp: i64,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
@@ -492,13 +470,13 @@ unsafe fn prepare_msg_raw(
|
|||||||
let mut to_id = 0;
|
let mut to_id = 0;
|
||||||
let mut location_id = 0;
|
let mut location_id = 0;
|
||||||
|
|
||||||
if !((*chat).typ == Chattype::Single
|
if !(chat.typ == Chattype::Single
|
||||||
|| (*chat).typ == Chattype::Group
|
|| chat.typ == Chattype::Group
|
||||||
|| (*chat).typ == Chattype::VerifiedGroup)
|
|| chat.typ == Chattype::VerifiedGroup)
|
||||||
{
|
{
|
||||||
error!(context, 0, "Cannot send to chat type #{}.", (*chat).typ,);
|
error!(context, 0, "Cannot send to chat type #{}.", chat.typ,);
|
||||||
} else if ((*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup)
|
} else if (chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup)
|
||||||
&& 0 == dc_is_contact_in_chat(context, (*chat).id, 1 as u32)
|
&& 0 == dc_is_contact_in_chat(context, chat.id, 1 as u32)
|
||||||
{
|
{
|
||||||
log_event!(
|
log_event!(
|
||||||
context,
|
context,
|
||||||
@@ -513,35 +491,33 @@ unsafe fn prepare_msg_raw(
|
|||||||
} else {
|
} else {
|
||||||
let from_c = CString::yolo(from.unwrap());
|
let from_c = CString::yolo(from.unwrap());
|
||||||
new_rfc724_mid = dc_create_outgoing_rfc724_mid(
|
new_rfc724_mid = dc_create_outgoing_rfc724_mid(
|
||||||
if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
(*chat).grpid
|
chat.grpid
|
||||||
} else {
|
} else {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
},
|
},
|
||||||
from_c.as_ptr(),
|
from_c.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (*chat).typ == Chattype::Single {
|
if chat.typ == Chattype::Single {
|
||||||
if let Some(id) = context.sql.query_row_col(
|
if let Some(id) = context.sql.query_row_col(
|
||||||
context,
|
context,
|
||||||
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
||||||
params![(*chat).id as i32],
|
params![chat.id as i32],
|
||||||
0,
|
0,
|
||||||
) {
|
) {
|
||||||
to_id = id;
|
to_id = id;
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
context,
|
context,
|
||||||
0,
|
0, "Cannot send message, contact for chat #{} not found.", chat.id,
|
||||||
"Cannot send message, contact for chat #{} not found.",
|
|
||||||
(*chat).id,
|
|
||||||
);
|
);
|
||||||
OK_TO_CONTINUE = false;
|
OK_TO_CONTINUE = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
|
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
|
||||||
(*chat).param.remove(Param::Unpromoted);
|
chat.param.remove(Param::Unpromoted);
|
||||||
dc_chat_update_param(chat);
|
dc_chat_update_param(chat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,7 +548,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
||||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
||||||
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
||||||
params![(*chat).id],
|
params![chat.id],
|
||||||
|row| {
|
|row| {
|
||||||
let state: String = row.get(1)?;
|
let state: String = row.get(1)?;
|
||||||
|
|
||||||
@@ -609,8 +585,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
if 0 != can_encrypt {
|
if 0 != can_encrypt {
|
||||||
if 0 != all_mutual {
|
if 0 != all_mutual {
|
||||||
do_guarantee_e2ee = 1;
|
do_guarantee_e2ee = 1;
|
||||||
} else if 0 != last_msg_in_chat_encrypted(context, &context.sql, (*chat).id)
|
} else if 0 != last_msg_in_chat_encrypted(context, &context.sql, chat.id) {
|
||||||
{
|
|
||||||
do_guarantee_e2ee = 1;
|
do_guarantee_e2ee = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,7 +657,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
params![
|
params![
|
||||||
timestamp,
|
timestamp,
|
||||||
DC_CONTACT_ID_SELF as i32,
|
DC_CONTACT_ID_SELF as i32,
|
||||||
(*chat).id as i32,
|
chat.id as i32,
|
||||||
(*msg)
|
(*msg)
|
||||||
.param
|
.param
|
||||||
.get_float(Param::SetLatitude)
|
.get_float(Param::SetLatitude)
|
||||||
@@ -715,7 +690,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
"INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?);",
|
"INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?);",
|
||||||
params![
|
params![
|
||||||
as_str(new_rfc724_mid),
|
as_str(new_rfc724_mid),
|
||||||
(*chat).id as i32,
|
chat.id as i32,
|
||||||
1i32,
|
1i32,
|
||||||
to_id as i32,
|
to_id as i32,
|
||||||
timestamp,
|
timestamp,
|
||||||
@@ -741,7 +716,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
"Cannot send message, cannot insert to database (chat #{}).",
|
"Cannot send message, cannot insert to database (chat #{}).",
|
||||||
(*chat).id,
|
chat.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -760,27 +735,24 @@ unsafe fn prepare_msg_raw(
|
|||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
unsafe fn get_parent_mime_headers(
|
unsafe fn get_parent_mime_headers(
|
||||||
chat: *const Chat,
|
chat: &Chat,
|
||||||
parent_rfc724_mid: *mut *mut libc::c_char,
|
parent_rfc724_mid: *mut *mut libc::c_char,
|
||||||
parent_in_reply_to: *mut *mut libc::c_char,
|
parent_in_reply_to: *mut *mut libc::c_char,
|
||||||
parent_references: *mut *mut libc::c_char,
|
parent_references: *mut *mut libc::c_char,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
let mut success = 0;
|
let mut success = 0;
|
||||||
|
|
||||||
if !(chat.is_null()
|
if !(parent_rfc724_mid.is_null() || parent_in_reply_to.is_null() || parent_references.is_null())
|
||||||
|| parent_rfc724_mid.is_null()
|
|
||||||
|| parent_in_reply_to.is_null()
|
|
||||||
|| parent_references.is_null())
|
|
||||||
{
|
{
|
||||||
// prefer a last message that isn't from us
|
// prefer a last message that isn't from us
|
||||||
success = (*chat)
|
success = chat
|
||||||
.context
|
.context
|
||||||
.sql
|
.sql
|
||||||
.query_row(
|
.query_row(
|
||||||
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
||||||
FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT max(timestamp) \
|
FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT max(timestamp) \
|
||||||
FROM msgs WHERE chat_id=?1 AND from_id!=?2);",
|
FROM msgs WHERE chat_id=?1 AND from_id!=?2);",
|
||||||
params![(*chat).id as i32, DC_CONTACT_ID_SELF as i32],
|
params![chat.id as i32, DC_CONTACT_ID_SELF as i32],
|
||||||
|row| {
|
|row| {
|
||||||
*parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
|
*parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
|
||||||
*parent_in_reply_to = row.get::<_, String>(1)?.strdup();
|
*parent_in_reply_to = row.get::<_, String>(1)?.strdup();
|
||||||
@@ -791,14 +763,14 @@ unsafe fn get_parent_mime_headers(
|
|||||||
.is_ok() as libc::c_int;
|
.is_ok() as libc::c_int;
|
||||||
|
|
||||||
if 0 == success {
|
if 0 == success {
|
||||||
success = (*chat)
|
success = chat
|
||||||
.context
|
.context
|
||||||
.sql
|
.sql
|
||||||
.query_row(
|
.query_row(
|
||||||
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
||||||
FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT min(timestamp) \
|
FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT min(timestamp) \
|
||||||
FROM msgs WHERE chat_id=?1 AND from_id==?2);",
|
FROM msgs WHERE chat_id=?1 AND from_id==?2);",
|
||||||
params![(*chat).id as i32, DC_CONTACT_ID_SELF as i32],
|
params![chat.id as i32, DC_CONTACT_ID_SELF as i32],
|
||||||
|row| {
|
|row| {
|
||||||
*parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
|
*parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
|
||||||
*parent_in_reply_to = row.get::<_, String>(1)?.strdup();
|
*parent_in_reply_to = row.get::<_, String>(1)?.strdup();
|
||||||
@@ -812,11 +784,8 @@ unsafe fn get_parent_mime_headers(
|
|||||||
success
|
success
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_is_self_talk(chat: *const Chat) -> libc::c_int {
|
pub unsafe fn dc_chat_is_self_talk(chat: &Chat) -> libc::c_int {
|
||||||
if chat.is_null() {
|
chat.param.exists(Param::Selftalk) as libc::c_int
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
(*chat).param.exists(Param::Selftalk) as libc::c_int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -847,12 +816,12 @@ unsafe fn last_msg_in_chat_encrypted(context: &Context, sql: &Sql, chat_id: u32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
pub unsafe fn dc_chat_update_param(chat: *mut Chat) -> libc::c_int {
|
pub unsafe fn dc_chat_update_param(chat: &mut Chat) -> libc::c_int {
|
||||||
sql::execute(
|
sql::execute(
|
||||||
(*chat).context,
|
chat.context,
|
||||||
&(*chat).context.sql,
|
&chat.context.sql,
|
||||||
"UPDATE chats SET param=? WHERE id=?",
|
"UPDATE chats SET param=? WHERE id=?",
|
||||||
params![(*chat).param.to_string(), (*chat).id as i32],
|
params![chat.param.to_string(), chat.id as i32],
|
||||||
)
|
)
|
||||||
.is_ok() as libc::c_int
|
.is_ok() as libc::c_int
|
||||||
}
|
}
|
||||||
@@ -1344,11 +1313,10 @@ pub fn dc_delete_chat(context: &Context, chat_id: u32) -> bool {
|
|||||||
if chat_id <= 9 {
|
if chat_id <= 9 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let obj = unsafe { dc_chat_new(context) };
|
|
||||||
if !dc_chat_load_from_db(obj, chat_id) {
|
if dc_chat_load_from_db(context, chat_id).is_err() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsafe { dc_chat_unref(obj) };
|
|
||||||
|
|
||||||
if sql::execute(
|
if sql::execute(
|
||||||
context,
|
context,
|
||||||
@@ -1423,20 +1391,8 @@ pub fn dc_get_chat_contacts(context: &Context, chat_id: u32) -> Vec<u32> {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_chat(context: &Context, chat_id: u32) -> *mut Chat {
|
pub fn dc_get_chat(context: &Context, chat_id: u32) -> Result<Chat, Error> {
|
||||||
let mut success: libc::c_int = 0i32;
|
dc_chat_load_from_db(context, chat_id)
|
||||||
let obj: *mut Chat = dc_chat_new(context);
|
|
||||||
|
|
||||||
if dc_chat_load_from_db(obj, chat_id) {
|
|
||||||
success = 1i32
|
|
||||||
}
|
|
||||||
|
|
||||||
if 0 != success {
|
|
||||||
obj
|
|
||||||
} else {
|
|
||||||
dc_chat_unref(obj);
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle group chats
|
// handle group chats
|
||||||
@@ -1521,19 +1477,25 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
|||||||
let mut OK_TO_CONTINUE = true;
|
let mut OK_TO_CONTINUE = true;
|
||||||
let mut success: libc::c_int = 0;
|
let mut success: libc::c_int = 0;
|
||||||
let contact = Contact::get_by_id(context, contact_id);
|
let contact = Contact::get_by_id(context, contact_id);
|
||||||
let chat: *mut Chat = dc_chat_new(context);
|
|
||||||
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
|
||||||
|
|
||||||
if !(contact.is_err() || chat_id <= 9 as libc::c_uint) {
|
if contact.is_err() || chat_id <= 9 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let mut msg = dc_msg_new_untyped(context);
|
||||||
|
|
||||||
dc_reset_gossiped_timestamp(context, chat_id);
|
dc_reset_gossiped_timestamp(context, chat_id);
|
||||||
let contact = contact.unwrap();
|
let contact = contact.unwrap();
|
||||||
|
|
||||||
/*this also makes sure, not contacts are added to special or normal chats*/
|
/*this also makes sure, not contacts are added to special or normal chats*/
|
||||||
|
let chat = dc_chat_load_from_db(context, chat_id);
|
||||||
|
|
||||||
if !(0 == real_group_exists(context, chat_id)
|
if !(0 == real_group_exists(context, chat_id)
|
||||||
|| !Contact::real_exists_by_id(context, contact_id)
|
|| !Contact::real_exists_by_id(context, contact_id)
|
||||||
&& contact_id != DC_CONTACT_ID_SELF as u32
|
&& contact_id != DC_CONTACT_ID_SELF as u32
|
||||||
|| !dc_chat_load_from_db(chat, chat_id))
|
|| chat.is_err())
|
||||||
{
|
{
|
||||||
|
let mut chat = chat.unwrap();
|
||||||
|
|
||||||
if !(dc_is_contact_in_chat(context, chat_id, 1 as u32) == 1) {
|
if !(dc_is_contact_in_chat(context, chat_id, 1 as u32) == 1) {
|
||||||
log_event!(
|
log_event!(
|
||||||
context,
|
context,
|
||||||
@@ -1543,11 +1505,9 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
||||||
if 0 != flags & 0x1
|
if 0 != flags & 0x1 && chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
|
||||||
&& (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 1
|
chat.param.remove(Param::Unpromoted);
|
||||||
{
|
dc_chat_update_param(&mut chat);
|
||||||
(*chat).param.remove(Param::Unpromoted);
|
|
||||||
dc_chat_update_param(chat);
|
|
||||||
}
|
}
|
||||||
let self_addr = context
|
let self_addr = context
|
||||||
.sql
|
.sql
|
||||||
@@ -1564,7 +1524,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// else continue and send status mail
|
// else continue and send status mail
|
||||||
if (*chat).typ == Chattype::VerifiedGroup {
|
if chat.typ == Chattype::VerifiedGroup {
|
||||||
if contact.is_verified() != VerifiedStatus::BidirectVerified {
|
if contact.is_verified() != VerifiedStatus::BidirectVerified {
|
||||||
error!(
|
error!(
|
||||||
context, 0,
|
context, 0,
|
||||||
@@ -1580,7 +1540,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if OK_TO_CONTINUE {
|
if OK_TO_CONTINUE {
|
||||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||||
(*msg).type_0 = Viewtype::Text;
|
(*msg).type_0 = Viewtype::Text;
|
||||||
(*msg).text = Some(context.stock_system_msg(
|
(*msg).text = Some(context.stock_system_msg(
|
||||||
StockMessage::MsgAddMember,
|
StockMessage::MsgAddMember,
|
||||||
@@ -1604,8 +1564,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
dc_chat_unref(chat);
|
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
|
|
||||||
success
|
success
|
||||||
@@ -1668,15 +1627,19 @@ pub unsafe fn dc_remove_contact_from_chat(
|
|||||||
contact_id: u32,
|
contact_id: u32,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
let mut success = 0;
|
let mut success = 0;
|
||||||
let chat: *mut Chat = dc_chat_new(context);
|
|
||||||
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
|
||||||
|
|
||||||
if !(chat_id <= 9 as libc::c_uint
|
if chat_id <= 9 || contact_id <= 9 && contact_id != DC_CONTACT_ID_SELF as u32 {
|
||||||
|| contact_id <= 9 as libc::c_uint && contact_id != DC_CONTACT_ID_SELF as u32)
|
return 0;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
let mut msg = dc_msg_new_untyped(context);
|
||||||
|
|
||||||
/* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */
|
/* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */
|
||||||
/* this allows to delete pending references to deleted contacts. Of course, this should _not_ happen. */
|
/* this allows to delete pending references to deleted contacts. Of course, this should _not_ happen. */
|
||||||
if !(0 == real_group_exists(context, chat_id) || !dc_chat_load_from_db(chat, chat_id)) {
|
let chat = dc_chat_load_from_db(context, chat_id);
|
||||||
|
|
||||||
|
if !(0 == real_group_exists(context, chat_id) || chat.is_err()) {
|
||||||
|
let chat = chat.unwrap();
|
||||||
if !(dc_is_contact_in_chat(context, chat_id, 1 as u32) == 1) {
|
if !(dc_is_contact_in_chat(context, chat_id, 1 as u32) == 1) {
|
||||||
log_event!(
|
log_event!(
|
||||||
context,
|
context,
|
||||||
@@ -1687,10 +1650,10 @@ pub unsafe fn dc_remove_contact_from_chat(
|
|||||||
} else {
|
} else {
|
||||||
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
||||||
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
||||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||||
(*msg).type_0 = Viewtype::Text;
|
(*msg).type_0 = Viewtype::Text;
|
||||||
if contact.id == DC_CONTACT_ID_SELF as u32 {
|
if contact.id == DC_CONTACT_ID_SELF as u32 {
|
||||||
dc_set_group_explicitly_left(context, (*chat).grpid);
|
dc_set_group_explicitly_left(context, chat.grpid);
|
||||||
(*msg).text = Some(context.stock_system_msg(
|
(*msg).text = Some(context.stock_system_msg(
|
||||||
StockMessage::MsgGroupLeft,
|
StockMessage::MsgGroupLeft,
|
||||||
"",
|
"",
|
||||||
@@ -1728,9 +1691,7 @@ pub unsafe fn dc_remove_contact_from_chat(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dc_chat_unref(chat);
|
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
|
|
||||||
success
|
success
|
||||||
@@ -1768,15 +1729,17 @@ pub unsafe fn dc_set_chat_name(
|
|||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
/* the function only sets the names of group chats; normal chats get their names from the contacts */
|
/* the function only sets the names of group chats; normal chats get their names from the contacts */
|
||||||
let mut success: libc::c_int = 0i32;
|
let mut success: libc::c_int = 0i32;
|
||||||
let chat: *mut Chat = dc_chat_new(context);
|
let mut msg = dc_msg_new_untyped(context);
|
||||||
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
|
||||||
|
|
||||||
if !(new_name.is_null()
|
if new_name.is_null() || *new_name.offset(0isize) as libc::c_int == 0 || chat_id <= 9 {
|
||||||
|| *new_name.offset(0isize) as libc::c_int == 0i32
|
return 0;
|
||||||
|| chat_id <= 9i32 as libc::c_uint)
|
}
|
||||||
{
|
|
||||||
if !(0i32 == real_group_exists(context, chat_id) || !dc_chat_load_from_db(chat, chat_id)) {
|
let chat = dc_chat_load_from_db(context, chat_id);
|
||||||
if strcmp((*chat).name, new_name) == 0i32 {
|
|
||||||
|
if !(0i32 == real_group_exists(context, chat_id) || chat.is_err()) {
|
||||||
|
let chat = chat.unwrap();
|
||||||
|
if strcmp(chat.name, new_name) == 0i32 {
|
||||||
success = 1i32
|
success = 1i32
|
||||||
} else if !(dc_is_contact_in_chat(context, chat_id, 1i32 as u32) == 1i32) {
|
} else if !(dc_is_contact_in_chat(context, chat_id, 1i32 as u32) == 1i32) {
|
||||||
log_event!(
|
log_event!(
|
||||||
@@ -1799,17 +1762,17 @@ pub unsafe fn dc_set_chat_name(
|
|||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||||
(*msg).type_0 = Viewtype::Text;
|
(*msg).type_0 = Viewtype::Text;
|
||||||
(*msg).text = Some(context.stock_system_msg(
|
(*msg).text = Some(context.stock_system_msg(
|
||||||
StockMessage::MsgGrpName,
|
StockMessage::MsgGrpName,
|
||||||
as_str((*chat).name),
|
as_str(chat.name),
|
||||||
as_str(new_name),
|
as_str(new_name),
|
||||||
DC_CONTACT_ID_SELF as u32,
|
DC_CONTACT_ID_SELF as u32,
|
||||||
));
|
));
|
||||||
(*msg).param.set_int(Param::Cmd, 2);
|
(*msg).param.set_int(Param::Cmd, 2);
|
||||||
if !(*chat).name.is_null() {
|
if !chat.name.is_null() {
|
||||||
(*msg).param.set(Param::Arg, as_str((*chat).name));
|
(*msg).param.set(Param::Arg, as_str(chat.name));
|
||||||
}
|
}
|
||||||
(*msg).id = dc_send_msg(context, chat_id, msg);
|
(*msg).id = dc_send_msg(context, chat_id, msg);
|
||||||
context.call_cb(
|
context.call_cb(
|
||||||
@@ -1823,13 +1786,11 @@ pub unsafe fn dc_set_chat_name(
|
|||||||
chat_id as uintptr_t,
|
chat_id as uintptr_t,
|
||||||
0i32 as uintptr_t,
|
0i32 as uintptr_t,
|
||||||
);
|
);
|
||||||
success = 1i32
|
success = 1i32;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_chat_unref(chat);
|
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
|
|
||||||
success
|
success
|
||||||
@@ -1844,11 +1805,17 @@ pub unsafe fn dc_set_chat_profile_image(
|
|||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
let mut OK_TO_CONTINUE = true;
|
let mut OK_TO_CONTINUE = true;
|
||||||
let mut success: libc::c_int = 0i32;
|
let mut success: libc::c_int = 0i32;
|
||||||
let chat: *mut Chat = dc_chat_new(context);
|
|
||||||
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
|
if chat_id <= 9 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut msg = dc_msg_new_untyped(context);
|
||||||
let mut new_image_rel: *mut libc::c_char = ptr::null_mut();
|
let mut new_image_rel: *mut libc::c_char = ptr::null_mut();
|
||||||
if !(chat_id <= 9i32 as libc::c_uint) {
|
if !(chat_id <= 9i32 as libc::c_uint) {
|
||||||
if !(0i32 == real_group_exists(context, chat_id) || !dc_chat_load_from_db(chat, chat_id)) {
|
let chat = dc_chat_load_from_db(context, chat_id);
|
||||||
|
if !(0i32 == real_group_exists(context, chat_id) || chat.is_err()) {
|
||||||
|
let mut chat = chat.unwrap();
|
||||||
if !(dc_is_contact_in_chat(context, chat_id, 1i32 as u32) == 1i32) {
|
if !(dc_is_contact_in_chat(context, chat_id, 1i32 as u32) == 1i32) {
|
||||||
log_event!(
|
log_event!(
|
||||||
context,
|
context,
|
||||||
@@ -1866,12 +1833,11 @@ pub unsafe fn dc_set_chat_profile_image(
|
|||||||
} else {
|
} else {
|
||||||
OK_TO_CONTINUE = false;
|
OK_TO_CONTINUE = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if OK_TO_CONTINUE {
|
if OK_TO_CONTINUE {
|
||||||
(*chat)
|
chat.param.set(Param::ProfileImage, as_str(new_image_rel));
|
||||||
.param
|
if !(0 == dc_chat_update_param(&mut chat)) {
|
||||||
.set(Param::ProfileImage, as_str(new_image_rel));
|
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
||||||
if !(0 == dc_chat_update_param(chat)) {
|
|
||||||
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
|
|
||||||
(*msg).param.set_int(Param::Cmd, 3);
|
(*msg).param.set_int(Param::Cmd, 3);
|
||||||
(*msg).param.set(Param::Arg, as_str(new_image_rel));
|
(*msg).param.set(Param::Arg, as_str(new_image_rel));
|
||||||
(*msg).type_0 = Viewtype::Text;
|
(*msg).type_0 = Viewtype::Text;
|
||||||
@@ -1897,14 +1863,12 @@ pub unsafe fn dc_set_chat_profile_image(
|
|||||||
chat_id as uintptr_t,
|
chat_id as uintptr_t,
|
||||||
0i32 as uintptr_t,
|
0i32 as uintptr_t,
|
||||||
);
|
);
|
||||||
success = 1i32
|
success = 1i32;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_chat_unref(chat);
|
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
free(new_image_rel as *mut libc::c_void);
|
free(new_image_rel as *mut libc::c_void);
|
||||||
|
|
||||||
@@ -1922,12 +1886,11 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let msg = dc_msg_new_untyped(context);
|
let msg = dc_msg_new_untyped(context);
|
||||||
let chat = dc_chat_new(context);
|
|
||||||
let mut created_db_entries = Vec::new();
|
let mut created_db_entries = Vec::new();
|
||||||
let mut curr_timestamp: i64;
|
let mut curr_timestamp: i64;
|
||||||
|
|
||||||
dc_unarchive_chat(context, chat_id);
|
dc_unarchive_chat(context, chat_id);
|
||||||
if dc_chat_load_from_db(chat, chat_id) {
|
if let Ok(mut chat) = dc_chat_load_from_db(context, chat_id) {
|
||||||
curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt);
|
curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt);
|
||||||
let idsstr = std::slice::from_raw_parts(msg_ids, msg_cnt as usize)
|
let idsstr = std::slice::from_raw_parts(msg_ids, msg_cnt as usize)
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1967,7 +1930,7 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
if (*msg).state == DC_STATE_OUT_PREPARING {
|
if (*msg).state == DC_STATE_OUT_PREPARING {
|
||||||
let fresh9 = curr_timestamp;
|
let fresh9 = curr_timestamp;
|
||||||
curr_timestamp = curr_timestamp + 1;
|
curr_timestamp = curr_timestamp + 1;
|
||||||
new_msg_id = prepare_msg_raw(context, chat, msg, fresh9);
|
new_msg_id = prepare_msg_raw(context, &mut chat, msg, fresh9);
|
||||||
let save_param = (*msg).param.clone();
|
let save_param = (*msg).param.clone();
|
||||||
(*msg).param = original_param;
|
(*msg).param = original_param;
|
||||||
(*msg).id = src_msg_id as u32;
|
(*msg).id = src_msg_id as u32;
|
||||||
@@ -1987,7 +1950,7 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
(*msg).state = DC_STATE_OUT_PENDING;
|
(*msg).state = DC_STATE_OUT_PENDING;
|
||||||
let fresh10 = curr_timestamp;
|
let fresh10 = curr_timestamp;
|
||||||
curr_timestamp = curr_timestamp + 1;
|
curr_timestamp = curr_timestamp + 1;
|
||||||
new_msg_id = prepare_msg_raw(context, chat, msg, fresh10);
|
new_msg_id = prepare_msg_raw(context, &mut chat, msg, fresh10);
|
||||||
dc_job_send_msg(context, new_msg_id);
|
dc_job_send_msg(context, new_msg_id);
|
||||||
}
|
}
|
||||||
created_db_entries.push(chat_id);
|
created_db_entries.push(chat_id);
|
||||||
@@ -2003,60 +1966,49 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
dc_chat_unref(chat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_id(chat: *const Chat) -> u32 {
|
pub unsafe fn dc_chat_get_id(chat: &Chat) -> u32 {
|
||||||
if chat.is_null() {
|
chat.id
|
||||||
return 0i32 as u32;
|
|
||||||
}
|
|
||||||
(*chat).id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_type(chat: *const Chat) -> Chattype {
|
pub unsafe fn dc_chat_get_type(chat: &Chat) -> Chattype {
|
||||||
assert!(!chat.is_null());
|
chat.typ
|
||||||
(*chat).typ
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_name(chat: *const Chat) -> *mut libc::c_char {
|
pub unsafe fn dc_chat_get_name(chat: &Chat) -> *mut libc::c_char {
|
||||||
if chat.is_null() {
|
dc_strdup(chat.name)
|
||||||
return dc_strdup(b"Err\x00" as *const u8 as *const libc::c_char);
|
|
||||||
}
|
|
||||||
dc_strdup((*chat).name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_subtitle(chat: *const Chat) -> *mut libc::c_char {
|
pub unsafe fn dc_chat_get_subtitle(chat: &Chat) -> *mut libc::c_char {
|
||||||
/* returns either the address or the number of chat members */
|
/* returns either the address or the number of chat members */
|
||||||
if chat.is_null() {
|
|
||||||
return dc_strdup(b"Err\x00" as *const u8 as *const libc::c_char);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut ret: *mut libc::c_char = std::ptr::null_mut();
|
let mut ret: *mut libc::c_char = std::ptr::null_mut();
|
||||||
if (*chat).typ == Chattype::Single && (*chat).param.exists(Param::Selftalk) {
|
if chat.typ == Chattype::Single && chat.param.exists(Param::Selftalk) {
|
||||||
ret = (*chat)
|
ret = chat
|
||||||
.context
|
.context
|
||||||
.stock_str(StockMessage::SelfTalkSubTitle)
|
.stock_str(StockMessage::SelfTalkSubTitle)
|
||||||
.strdup();
|
.strdup();
|
||||||
} else if (*chat).typ == Chattype::Single {
|
} else if chat.typ == Chattype::Single {
|
||||||
let ret_raw: String = (*chat)
|
let ret_raw: String = chat
|
||||||
.context
|
.context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_row_col(
|
||||||
(*chat).context,
|
chat.context,
|
||||||
"SELECT c.addr FROM chats_contacts cc \
|
"SELECT c.addr FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON c.id=cc.contact_id \
|
LEFT JOIN contacts c ON c.id=cc.contact_id \
|
||||||
WHERE cc.chat_id=?;",
|
WHERE cc.chat_id=?;",
|
||||||
params![(*chat).id as i32],
|
params![chat.id as i32],
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| "Err".into());
|
.unwrap_or_else(|| "Err".into());
|
||||||
ret = ret_raw.strdup();
|
ret = ret_raw.strdup();
|
||||||
} else if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
} else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
if (*chat).id == 1 {
|
if chat.id == 1 {
|
||||||
ret = (*chat).context.stock_str(StockMessage::DeadDrop).strdup();
|
ret = chat.context.stock_str(StockMessage::DeadDrop).strdup();
|
||||||
} else {
|
} else {
|
||||||
let cnt = dc_get_chat_contact_cnt((*chat).context, (*chat).id);
|
let cnt = dc_get_chat_contact_cnt(chat.context, chat.id);
|
||||||
ret = (*chat)
|
ret = chat
|
||||||
.context
|
.context
|
||||||
.stock_string_repl_int(StockMessage::Member, cnt)
|
.stock_string_repl_int(StockMessage::Member, cnt)
|
||||||
.strdup();
|
.strdup();
|
||||||
@@ -2081,84 +2033,67 @@ pub fn dc_get_chat_contact_cnt(context: &Context, chat_id: u32) -> libc::c_int {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char {
|
pub unsafe fn dc_chat_get_profile_image(chat: &Chat) -> *mut libc::c_char {
|
||||||
let mut image_rel: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
||||||
let mut image_abs: *mut libc::c_char = 0 as *mut libc::c_char;
|
let mut image_abs: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||||
|
|
||||||
if !chat.is_null() {
|
let image_rel = chat
|
||||||
image_rel = (*chat)
|
|
||||||
.param
|
.param
|
||||||
.get(Param::ProfileImage)
|
.get(Param::ProfileImage)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.strdup();
|
.strdup();
|
||||||
if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int {
|
if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int {
|
||||||
image_abs = dc_get_abs_path((*chat).context, image_rel)
|
image_abs = dc_get_abs_path(chat.context, image_rel)
|
||||||
} else if (*chat).typ == Chattype::Single {
|
} else if chat.typ == Chattype::Single {
|
||||||
let contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
|
let contacts = dc_get_chat_contacts(chat.context, chat.id);
|
||||||
if !contacts.is_empty() {
|
if !contacts.is_empty() {
|
||||||
if let Ok(contact) = Contact::get_by_id((*chat).context, contacts[0]) {
|
if let Ok(contact) = Contact::get_by_id(chat.context, contacts[0]) {
|
||||||
if let Some(img) = contact.get_profile_image() {
|
if let Some(img) = contact.get_profile_image() {
|
||||||
image_abs = img.strdup();
|
image_abs = img.strdup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(image_rel as *mut libc::c_void);
|
free(image_rel as *mut libc::c_void);
|
||||||
|
|
||||||
image_abs
|
image_abs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_chat_get_color(chat: *const Chat) -> u32 {
|
pub unsafe fn dc_chat_get_color(chat: &Chat) -> u32 {
|
||||||
let mut color: u32 = 0i32 as u32;
|
let mut color: u32 = 0i32 as u32;
|
||||||
|
|
||||||
if !chat.is_null() {
|
if chat.typ == Chattype::Single {
|
||||||
if (*chat).typ == Chattype::Single {
|
let contacts = dc_get_chat_contacts(chat.context, chat.id);
|
||||||
let contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
|
|
||||||
if !contacts.is_empty() {
|
if !contacts.is_empty() {
|
||||||
if let Ok(contact) = Contact::get_by_id((*chat).context, contacts[0]) {
|
if let Ok(contact) = Contact::get_by_id(chat.context, contacts[0]) {
|
||||||
color = contact.get_color();
|
color = contact.get_color();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
color = dc_str_to_color((*chat).name) as u32
|
color = dc_str_to_color(chat.name) as u32
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color
|
color
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
pub unsafe fn dc_chat_get_archived(chat: *const Chat) -> bool {
|
pub unsafe fn dc_chat_get_archived(chat: &Chat) -> bool {
|
||||||
if chat.is_null() {
|
chat.archived
|
||||||
return false;
|
|
||||||
}
|
|
||||||
(*chat).archived
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
pub unsafe fn dc_chat_is_unpromoted(chat: *const Chat) -> libc::c_int {
|
pub unsafe fn dc_chat_is_unpromoted(chat: &Chat) -> libc::c_int {
|
||||||
if chat.is_null() {
|
chat.param.get_int(Param::Unpromoted).unwrap_or_default() as libc::c_int
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
(*chat).param.get_int(Param::Unpromoted).unwrap_or_default() as libc::c_int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
pub unsafe fn dc_chat_is_verified(chat: *const Chat) -> libc::c_int {
|
pub unsafe fn dc_chat_is_verified(chat: &Chat) -> libc::c_int {
|
||||||
if chat.is_null() {
|
(chat.typ == Chattype::VerifiedGroup) as libc::c_int
|
||||||
return 0i32;
|
|
||||||
}
|
|
||||||
((*chat).typ == Chattype::VerifiedGroup) as libc::c_int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
pub unsafe fn dc_chat_is_sending_locations(chat: *const Chat) -> bool {
|
pub unsafe fn dc_chat_is_sending_locations(chat: &Chat) -> bool {
|
||||||
if chat.is_null() {
|
chat.is_sending_locations
|
||||||
return false;
|
|
||||||
}
|
|
||||||
(*chat).is_sending_locations
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_get_chat_cnt(context: &Context) -> usize {
|
pub fn dc_get_chat_cnt(context: &Context) -> usize {
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ impl<'a> Chatlist<'a> {
|
|||||||
/// - dc_lot_t::timestamp: the timestamp of the message. 0 if not applicable.
|
/// - dc_lot_t::timestamp: the timestamp of the message. 0 if not applicable.
|
||||||
/// - dc_lot_t::state: The state of the message as one of the DC_STATE_* constants (see #dc_msg_get_state()).
|
/// - dc_lot_t::state: The state of the message as one of the DC_STATE_* constants (see #dc_msg_get_state()).
|
||||||
// 0 if not applicable.
|
// 0 if not applicable.
|
||||||
pub unsafe fn get_summary(&self, index: usize, mut chat: *mut Chat<'a>) -> *mut dc_lot_t {
|
pub unsafe fn get_summary(&self, index: usize, chat: Option<&Chat<'a>>) -> *mut dc_lot_t {
|
||||||
// The summary is created by the chat, not by the last message.
|
// The summary is created by the chat, not by the last message.
|
||||||
// This is because we may want to display drafts here or stuff as
|
// This is because we may want to display drafts here or stuff as
|
||||||
// "is typing".
|
// "is typing".
|
||||||
@@ -261,26 +261,27 @@ impl<'a> Chatlist<'a> {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastmsg_id = self.ids[index].1;
|
let chat_loaded: Chat;
|
||||||
let mut lastcontact = None;
|
let chat = if let Some(chat) = chat {
|
||||||
|
chat
|
||||||
if chat.is_null() {
|
} else {
|
||||||
chat = dc_chat_new(self.context);
|
if let Ok(chat) = dc_get_chat(self.context, self.ids[index].0) {
|
||||||
let chat_to_delete = chat;
|
chat_loaded = chat;
|
||||||
if !dc_chat_load_from_db(chat, self.ids[index].0) {
|
&chat_loaded
|
||||||
(*ret).text2 = "ErrCannotReadChat".strdup();
|
} else {
|
||||||
dc_chat_unref(chat_to_delete);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let lastmsg_id = self.ids[index].1;
|
||||||
|
let mut lastcontact = None;
|
||||||
|
|
||||||
let lastmsg = if 0 != lastmsg_id {
|
let lastmsg = if 0 != lastmsg_id {
|
||||||
let lastmsg = dc_msg_new_untyped(self.context);
|
let lastmsg = dc_msg_new_untyped(self.context);
|
||||||
dc_msg_load_from_db(lastmsg, self.context, lastmsg_id);
|
dc_msg_load_from_db(lastmsg, self.context, lastmsg_id);
|
||||||
|
|
||||||
if (*lastmsg).from_id != 1 as libc::c_uint
|
if (*lastmsg).from_id != 1 as libc::c_uint
|
||||||
&& ((*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup)
|
&& (chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup)
|
||||||
{
|
{
|
||||||
lastcontact = Contact::load_from_db(self.context, (*lastmsg).from_id).ok();
|
lastcontact = Contact::load_from_db(self.context, (*lastmsg).from_id).ok();
|
||||||
}
|
}
|
||||||
@@ -289,7 +290,7 @@ impl<'a> Chatlist<'a> {
|
|||||||
std::ptr::null_mut()
|
std::ptr::null_mut()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (*chat).id == DC_CHAT_ID_ARCHIVED_LINK as u32 {
|
if chat.id == DC_CHAT_ID_ARCHIVED_LINK as u32 {
|
||||||
(*ret).text2 = dc_strdup(ptr::null())
|
(*ret).text2 = dc_strdup(ptr::null())
|
||||||
} else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_UNDEFINED as u32 {
|
} else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_UNDEFINED as u32 {
|
||||||
(*ret).text2 = self.context.stock_str(StockMessage::NoMessages).strdup();
|
(*ret).text2 = self.context.stock_str(StockMessage::NoMessages).strdup();
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_
|
|||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
}
|
}
|
||||||
unsafe fn dc_send_mdn(context: &Context, msg_id: uint32_t) {
|
unsafe fn dc_send_mdn(context: &Context, msg_id: uint32_t) {
|
||||||
let mut mimefactory: dc_mimefactory_t = dc_mimefactory_t {
|
let mut mimefactory = dc_mimefactory_t {
|
||||||
from_addr: ptr::null_mut(),
|
from_addr: ptr::null_mut(),
|
||||||
from_displayname: ptr::null_mut(),
|
from_displayname: ptr::null_mut(),
|
||||||
selfstatus: ptr::null_mut(),
|
selfstatus: ptr::null_mut(),
|
||||||
@@ -575,7 +575,7 @@ unsafe fn dc_send_mdn(context: &Context, msg_id: uint32_t) {
|
|||||||
rfc724_mid: ptr::null_mut(),
|
rfc724_mid: ptr::null_mut(),
|
||||||
loaded: DC_MF_NOTHING_LOADED,
|
loaded: DC_MF_NOTHING_LOADED,
|
||||||
msg: ptr::null_mut(),
|
msg: ptr::null_mut(),
|
||||||
chat: ptr::null_mut(),
|
chat: None,
|
||||||
increation: 0,
|
increation: 0,
|
||||||
in_reply_to: ptr::null_mut(),
|
in_reply_to: ptr::null_mut(),
|
||||||
references: ptr::null_mut(),
|
references: ptr::null_mut(),
|
||||||
@@ -587,7 +587,7 @@ unsafe fn dc_send_mdn(context: &Context, msg_id: uint32_t) {
|
|||||||
error: ptr::null_mut(),
|
error: ptr::null_mut(),
|
||||||
context,
|
context,
|
||||||
};
|
};
|
||||||
dc_mimefactory_init(&mut mimefactory, context);
|
|
||||||
if !(0 == dc_mimefactory_load_mdn(&mut mimefactory, msg_id)
|
if !(0 == dc_mimefactory_load_mdn(&mut mimefactory, msg_id)
|
||||||
|| 0 == dc_mimefactory_render(&mut mimefactory))
|
|| 0 == dc_mimefactory_render(&mut mimefactory))
|
||||||
{
|
{
|
||||||
@@ -1014,7 +1014,7 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
|
|||||||
rfc724_mid: 0 as *mut libc::c_char,
|
rfc724_mid: 0 as *mut libc::c_char,
|
||||||
loaded: DC_MF_NOTHING_LOADED,
|
loaded: DC_MF_NOTHING_LOADED,
|
||||||
msg: 0 as *mut dc_msg_t,
|
msg: 0 as *mut dc_msg_t,
|
||||||
chat: 0 as *mut Chat,
|
chat: None,
|
||||||
increation: 0,
|
increation: 0,
|
||||||
in_reply_to: 0 as *mut libc::c_char,
|
in_reply_to: 0 as *mut libc::c_char,
|
||||||
references: 0 as *mut libc::c_char,
|
references: 0 as *mut libc::c_char,
|
||||||
@@ -1026,7 +1026,7 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
|
|||||||
error: 0 as *mut libc::c_char,
|
error: 0 as *mut libc::c_char,
|
||||||
context,
|
context,
|
||||||
};
|
};
|
||||||
dc_mimefactory_init(&mut mimefactory, context);
|
|
||||||
/* load message data */
|
/* load message data */
|
||||||
if 0 == dc_mimefactory_load_msg(&mut mimefactory, msg_id) || mimefactory.from_addr.is_null() {
|
if 0 == dc_mimefactory_load_msg(&mut mimefactory, msg_id) || mimefactory.from_addr.is_null() {
|
||||||
warn!(
|
warn!(
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ pub unsafe fn dc_lot_get_timestamp(lot: *const dc_lot_t) -> i64 {
|
|||||||
pub unsafe fn dc_lot_fill(
|
pub unsafe fn dc_lot_fill(
|
||||||
mut lot: *mut dc_lot_t,
|
mut lot: *mut dc_lot_t,
|
||||||
msg: *mut dc_msg_t,
|
msg: *mut dc_msg_t,
|
||||||
chat: *const Chat,
|
chat: &Chat,
|
||||||
contact: Option<&Contact>,
|
contact: Option<&Contact>,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) {
|
) {
|
||||||
@@ -142,15 +142,12 @@ pub unsafe fn dc_lot_fill(
|
|||||||
(*lot).text1 = context.stock_str(StockMessage::SelfMsg).strdup();
|
(*lot).text1 = context.stock_str(StockMessage::SelfMsg).strdup();
|
||||||
(*lot).text1_meaning = 3i32
|
(*lot).text1_meaning = 3i32
|
||||||
}
|
}
|
||||||
} else if chat.is_null() {
|
} else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
(*lot).text1 = 0 as *mut libc::c_char;
|
|
||||||
(*lot).text1_meaning = 0i32
|
|
||||||
} else if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
|
||||||
if 0 != dc_msg_is_info(msg) || contact.is_none() {
|
if 0 != dc_msg_is_info(msg) || contact.is_none() {
|
||||||
(*lot).text1 = 0 as *mut libc::c_char;
|
(*lot).text1 = 0 as *mut libc::c_char;
|
||||||
(*lot).text1_meaning = 0i32
|
(*lot).text1_meaning = 0i32
|
||||||
} else {
|
} else {
|
||||||
if !chat.is_null() && (*chat).id == 1i32 as libc::c_uint {
|
if chat.id == 1 {
|
||||||
if let Some(contact) = contact {
|
if let Some(contact) = contact {
|
||||||
(*lot).text1 = contact.get_display_name().strdup();
|
(*lot).text1 = contact.get_display_name().strdup();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ use crate::stock::StockMessage;
|
|||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::x::*;
|
use crate::x::*;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Clone)]
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct dc_mimefactory_t<'a> {
|
pub struct dc_mimefactory_t<'a> {
|
||||||
pub from_addr: *mut libc::c_char,
|
pub from_addr: *mut libc::c_char,
|
||||||
@@ -37,7 +36,7 @@ pub struct dc_mimefactory_t<'a> {
|
|||||||
pub rfc724_mid: *mut libc::c_char,
|
pub rfc724_mid: *mut libc::c_char,
|
||||||
pub loaded: dc_mimefactory_loaded_t,
|
pub loaded: dc_mimefactory_loaded_t,
|
||||||
pub msg: *mut dc_msg_t<'a>,
|
pub msg: *mut dc_msg_t<'a>,
|
||||||
pub chat: *mut Chat<'a>,
|
pub chat: Option<Chat<'a>>,
|
||||||
pub increation: libc::c_int,
|
pub increation: libc::c_int,
|
||||||
pub in_reply_to: *mut libc::c_char,
|
pub in_reply_to: *mut libc::c_char,
|
||||||
pub references: *mut libc::c_char,
|
pub references: *mut libc::c_char,
|
||||||
@@ -56,18 +55,6 @@ const DC_MF_MDN_LOADED: dc_mimefactory_loaded_t = 2;
|
|||||||
pub const DC_MF_MSG_LOADED: dc_mimefactory_loaded_t = 1;
|
pub const DC_MF_MSG_LOADED: dc_mimefactory_loaded_t = 1;
|
||||||
pub const DC_MF_NOTHING_LOADED: dc_mimefactory_loaded_t = 0;
|
pub const DC_MF_NOTHING_LOADED: dc_mimefactory_loaded_t = 0;
|
||||||
|
|
||||||
pub unsafe fn dc_mimefactory_init<'a>(factory: *mut dc_mimefactory_t<'a>, context: &'a Context) {
|
|
||||||
if factory.is_null() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(
|
|
||||||
factory as *mut libc::c_void,
|
|
||||||
0,
|
|
||||||
::std::mem::size_of::<dc_mimefactory_t>(),
|
|
||||||
);
|
|
||||||
(*factory).context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn dc_mimefactory_empty(mut factory: *mut dc_mimefactory_t) {
|
pub unsafe fn dc_mimefactory_empty(mut factory: *mut dc_mimefactory_t) {
|
||||||
if factory.is_null() {
|
if factory.is_null() {
|
||||||
return;
|
return;
|
||||||
@@ -92,8 +79,7 @@ pub unsafe fn dc_mimefactory_empty(mut factory: *mut dc_mimefactory_t) {
|
|||||||
}
|
}
|
||||||
dc_msg_unref((*factory).msg);
|
dc_msg_unref((*factory).msg);
|
||||||
(*factory).msg = 0 as *mut dc_msg_t;
|
(*factory).msg = 0 as *mut dc_msg_t;
|
||||||
dc_chat_unref((*factory).chat);
|
(*factory).chat = None;
|
||||||
(*factory).chat = 0 as *mut Chat;
|
|
||||||
free((*factory).in_reply_to as *mut libc::c_void);
|
free((*factory).in_reply_to as *mut libc::c_void);
|
||||||
(*factory).in_reply_to = 0 as *mut libc::c_char;
|
(*factory).in_reply_to = 0 as *mut libc::c_char;
|
||||||
free((*factory).references as *mut libc::c_void);
|
free((*factory).references as *mut libc::c_void);
|
||||||
@@ -124,13 +110,16 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
(*factory).recipients_names = clist_new();
|
(*factory).recipients_names = clist_new();
|
||||||
(*factory).recipients_addr = clist_new();
|
(*factory).recipients_addr = clist_new();
|
||||||
(*factory).msg = dc_msg_new_untyped(context);
|
(*factory).msg = dc_msg_new_untyped(context);
|
||||||
(*factory).chat = dc_chat_new(context);
|
|
||||||
if dc_msg_load_from_db((*factory).msg, context, msg_id)
|
if dc_msg_load_from_db((*factory).msg, context, msg_id) {
|
||||||
&& dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id)
|
if let Ok(chat) = dc_chat_load_from_db(context, (*(*factory).msg).chat_id) {
|
||||||
{
|
(*factory).chat = Some(chat);
|
||||||
|
|
||||||
|
let chat = (*factory).chat.as_ref().unwrap();
|
||||||
|
|
||||||
load_from(factory);
|
load_from(factory);
|
||||||
(*factory).req_mdn = 0;
|
(*factory).req_mdn = 0;
|
||||||
if 0 != dc_chat_is_self_talk((*factory).chat) {
|
if 0 != dc_chat_is_self_talk(chat) {
|
||||||
clist_insert_after(
|
clist_insert_after(
|
||||||
(*factory).recipients_names,
|
(*factory).recipients_names,
|
||||||
(*(*factory).recipients_names).last,
|
(*(*factory).recipients_names).last,
|
||||||
@@ -159,7 +148,9 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
for row in rows {
|
for row in rows {
|
||||||
let (authname, addr) = row?;
|
let (authname, addr) = row?;
|
||||||
let addr_c = addr.strdup();
|
let addr_c = addr.strdup();
|
||||||
if clist_search_string_nocase((*factory).recipients_addr, addr_c) == 0 {
|
if clist_search_string_nocase((*factory).recipients_addr, addr_c)
|
||||||
|
== 0
|
||||||
|
{
|
||||||
clist_insert_after(
|
clist_insert_after(
|
||||||
(*factory).recipients_names,
|
(*factory).recipients_names,
|
||||||
(*(*factory).recipients_names).last,
|
(*(*factory).recipients_names).last,
|
||||||
@@ -167,7 +158,8 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
authname.strdup()
|
authname.strdup()
|
||||||
} else {
|
} else {
|
||||||
std::ptr::null_mut()
|
std::ptr::null_mut()
|
||||||
} as *mut libc::c_void,
|
}
|
||||||
|
as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
clist_insert_after(
|
clist_insert_after(
|
||||||
(*factory).recipients_addr,
|
(*factory).recipients_addr,
|
||||||
@@ -187,7 +179,8 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if command == 5 {
|
if command == 5 {
|
||||||
let email_to_remove = (*(*factory).msg).param.get(Param::Arg).unwrap_or_default();
|
let email_to_remove =
|
||||||
|
(*(*factory).msg).param.get(Param::Arg).unwrap_or_default();
|
||||||
let email_to_remove_c = email_to_remove.strdup();
|
let email_to_remove_c = email_to_remove.strdup();
|
||||||
|
|
||||||
let self_addr = context
|
let self_addr = context
|
||||||
@@ -250,6 +243,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
(*factory).timestamp = (*(*factory).msg).timestamp_sort;
|
(*factory).timestamp = (*(*factory).msg).timestamp_sort;
|
||||||
(*factory).rfc724_mid = dc_strdup((*(*factory).msg).rfc724_mid)
|
(*factory).rfc724_mid = dc_strdup((*(*factory).msg).rfc724_mid)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if 0 != success {
|
if 0 != success {
|
||||||
(*factory).increation = dc_msg_is_increation((*factory).msg)
|
(*factory).increation = dc_msg_is_increation((*factory).msg)
|
||||||
}
|
}
|
||||||
@@ -514,11 +508,11 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
if (*factory).loaded as libc::c_uint == DC_MF_MSG_LOADED as libc::c_int as libc::c_uint {
|
if (*factory).loaded as libc::c_uint == DC_MF_MSG_LOADED as libc::c_int as libc::c_uint {
|
||||||
/* Render a normal message
|
/* Render a normal message
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
let chat: *mut Chat = (*factory).chat;
|
let chat = (*factory).chat.as_ref().unwrap();
|
||||||
let msg: *mut dc_msg_t = (*factory).msg;
|
let msg = (*factory).msg;
|
||||||
let mut meta_part: *mut mailmime = 0 as *mut mailmime;
|
let mut meta_part: *mut mailmime = 0 as *mut mailmime;
|
||||||
let mut placeholdertext: *mut libc::c_char = 0 as *mut libc::c_char;
|
let mut placeholdertext: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||||
if (*chat).typ == Chattype::VerifiedGroup {
|
if chat.typ == Chattype::VerifiedGroup {
|
||||||
mailimf_fields_add(
|
mailimf_fields_add(
|
||||||
imf_fields,
|
imf_fields,
|
||||||
mailimf_field_new_custom(
|
mailimf_field_new_custom(
|
||||||
@@ -541,27 +535,27 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*chat).gossiped_timestamp == 0
|
if chat.gossiped_timestamp == 0
|
||||||
|| ((*chat).gossiped_timestamp + (2 * 24 * 60 * 60)) < time()
|
|| (chat.gossiped_timestamp + (2 * 24 * 60 * 60)) < time()
|
||||||
{
|
{
|
||||||
do_gossip = 1
|
do_gossip = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build header etc. */
|
/* build header etc. */
|
||||||
let command = (*msg).param.get_int(Param::Cmd).unwrap_or_default();
|
let command = (*msg).param.get_int(Param::Cmd).unwrap_or_default();
|
||||||
if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
mailimf_fields_add(
|
mailimf_fields_add(
|
||||||
imf_fields,
|
imf_fields,
|
||||||
mailimf_field_new_custom(
|
mailimf_field_new_custom(
|
||||||
strdup(b"Chat-Group-ID\x00" as *const u8 as *const libc::c_char),
|
strdup(b"Chat-Group-ID\x00" as *const u8 as *const libc::c_char),
|
||||||
dc_strdup((*chat).grpid),
|
dc_strdup(chat.grpid),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
mailimf_fields_add(
|
mailimf_fields_add(
|
||||||
imf_fields,
|
imf_fields,
|
||||||
mailimf_field_new_custom(
|
mailimf_field_new_custom(
|
||||||
strdup(b"Chat-Group-Name\x00" as *const u8 as *const libc::c_char),
|
strdup(b"Chat-Group-Name\x00" as *const u8 as *const libc::c_char),
|
||||||
dc_encode_header_words((*chat).name),
|
dc_encode_header_words(chat.name),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if command == 5 {
|
if command == 5 {
|
||||||
@@ -592,7 +586,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
email_to_add,
|
email_to_add,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
grpimage = (*chat).param.get(Param::ProfileImage);
|
grpimage = chat.param.get(Param::ProfileImage);
|
||||||
}
|
}
|
||||||
if 0 != (*msg).param.get_int(Param::Arg2).unwrap_or_default() & 0x1 {
|
if 0 != (*msg).param.get_int(Param::Arg2).unwrap_or_default() & 0x1 {
|
||||||
info!(
|
info!(
|
||||||
@@ -998,7 +992,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
e.as_ptr(),
|
e.as_ptr(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
subject_str = get_subject((*factory).chat, (*factory).msg, afwd_email)
|
subject_str = get_subject((*factory).chat.as_ref(), (*factory).msg, afwd_email)
|
||||||
}
|
}
|
||||||
subject = mailimf_subject_new(dc_encode_header_words(subject_str));
|
subject = mailimf_subject_new(dc_encode_header_words(subject_str));
|
||||||
mailimf_fields_add(
|
mailimf_fields_add(
|
||||||
@@ -1052,6 +1046,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
success = 1
|
success = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !message.is_null() {
|
if !message.is_null() {
|
||||||
mailmime_free(message);
|
mailmime_free(message);
|
||||||
}
|
}
|
||||||
@@ -1064,11 +1059,16 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get_subject(
|
unsafe fn get_subject(
|
||||||
chat: *const Chat,
|
chat: Option<&Chat>,
|
||||||
msg: *mut dc_msg_t,
|
msg: *mut dc_msg_t,
|
||||||
afwd_email: libc::c_int,
|
afwd_email: libc::c_int,
|
||||||
) -> *mut libc::c_char {
|
) -> *mut libc::c_char {
|
||||||
let context = (*chat).context;
|
if chat.is_none() {
|
||||||
|
return std::ptr::null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let chat = chat.unwrap();
|
||||||
|
let context = chat.context;
|
||||||
let ret: *mut libc::c_char;
|
let ret: *mut libc::c_char;
|
||||||
|
|
||||||
let raw_subject = {
|
let raw_subject = {
|
||||||
@@ -1089,10 +1089,10 @@ unsafe fn get_subject(
|
|||||||
};
|
};
|
||||||
if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 {
|
if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 {
|
||||||
ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup()
|
ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup()
|
||||||
} else if (*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup {
|
} else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||||
ret = dc_mprintf(
|
ret = dc_mprintf(
|
||||||
b"Chat: %s: %s%s\x00" as *const u8 as *const libc::c_char,
|
b"Chat: %s: %s%s\x00" as *const u8 as *const libc::c_char,
|
||||||
(*chat).name,
|
chat.name,
|
||||||
fwd,
|
fwd,
|
||||||
raw_subject,
|
raw_subject,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -745,22 +745,26 @@ pub unsafe fn dc_msg_get_showpadlock(msg: *const dc_msg_t) -> libc::c_int {
|
|||||||
|
|
||||||
pub unsafe fn dc_msg_get_summary<'a>(
|
pub unsafe fn dc_msg_get_summary<'a>(
|
||||||
msg: *mut dc_msg_t<'a>,
|
msg: *mut dc_msg_t<'a>,
|
||||||
mut chat: *const Chat<'a>,
|
chat: Option<&Chat<'a>>,
|
||||||
) -> *mut dc_lot_t {
|
) -> *mut dc_lot_t {
|
||||||
let mut ok_to_continue = true;
|
let ret = dc_lot_new();
|
||||||
let ret: *mut dc_lot_t = dc_lot_new();
|
|
||||||
let mut chat_to_delete: *mut Chat = 0 as *mut Chat;
|
|
||||||
|
|
||||||
if !msg.is_null() {
|
if msg.is_null() {
|
||||||
if chat.is_null() {
|
return ret;
|
||||||
chat_to_delete = dc_get_chat((*msg).context, (*msg).chat_id);
|
}
|
||||||
if chat_to_delete.is_null() {
|
|
||||||
ok_to_continue = false;
|
let chat_loaded: Chat;
|
||||||
|
let chat = if let Some(chat) = chat {
|
||||||
|
chat
|
||||||
} else {
|
} else {
|
||||||
chat = chat_to_delete;
|
if let Ok(chat) = dc_get_chat((*msg).context, (*msg).chat_id) {
|
||||||
|
chat_loaded = chat;
|
||||||
|
&chat_loaded
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
if ok_to_continue {
|
|
||||||
let contact = if (*msg).from_id != DC_CONTACT_ID_SELF as libc::c_uint
|
let contact = if (*msg).from_id != DC_CONTACT_ID_SELF as libc::c_uint
|
||||||
&& ((*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup)
|
&& ((*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup)
|
||||||
{
|
{
|
||||||
@@ -770,10 +774,6 @@ pub unsafe fn dc_msg_get_summary<'a>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
dc_lot_fill(ret, msg, chat, contact.as_ref(), (*msg).context);
|
dc_lot_fill(ret, msg, chat, contact.as_ref(), (*msg).context);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dc_chat_unref(chat_to_delete);
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1375,7 +1375,6 @@ unsafe fn create_or_lookup_group(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if 0 != ok {
|
if 0 != ok {
|
||||||
let chat = dc_chat_new(context);
|
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
@@ -1386,16 +1385,17 @@ unsafe fn create_or_lookup_group(
|
|||||||
to_string(grpimage)
|
to_string(grpimage)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
dc_chat_load_from_db(chat, chat_id);
|
if let Ok(mut chat) = dc_chat_load_from_db(context, chat_id) {
|
||||||
if grpimage.is_null() {
|
if grpimage.is_null() {
|
||||||
(*chat).param.remove(Param::ProfileImage);
|
chat.param.remove(Param::ProfileImage);
|
||||||
} else {
|
} else {
|
||||||
(*chat).param.set(Param::ProfileImage, as_str(grpimage));
|
chat.param.set(Param::ProfileImage, as_str(grpimage));
|
||||||
}
|
}
|
||||||
dc_chat_update_param(chat);
|
dc_chat_update_param(&mut chat);
|
||||||
dc_chat_unref(chat);
|
send_EVENT_CHAT_MODIFIED = 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(grpimage as *mut libc::c_void);
|
free(grpimage as *mut libc::c_void);
|
||||||
send_EVENT_CHAT_MODIFIED = 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
let mut fingerprint = 0 as *mut libc::c_char;
|
let mut fingerprint = 0 as *mut libc::c_char;
|
||||||
let mut invitenumber: *mut libc::c_char;
|
let mut invitenumber: *mut libc::c_char;
|
||||||
let mut auth: *mut libc::c_char;
|
let mut auth: *mut libc::c_char;
|
||||||
let mut chat = 0 as *mut Chat;
|
|
||||||
let mut group_name = 0 as *mut libc::c_char;
|
let mut group_name = 0 as *mut libc::c_char;
|
||||||
let mut group_name_urlencoded = 0 as *mut libc::c_char;
|
let mut group_name_urlencoded = 0 as *mut libc::c_char;
|
||||||
let mut qr: Option<String> = None;
|
let mut qr: Option<String> = None;
|
||||||
@@ -54,11 +53,10 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
}
|
}
|
||||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||||
|
|
||||||
let cleanup = |fingerprint, chat, group_name, group_name_urlencoded| {
|
let cleanup = |fingerprint, group_name, group_name_urlencoded| {
|
||||||
free(fingerprint as *mut libc::c_void);
|
free(fingerprint as *mut libc::c_void);
|
||||||
free(invitenumber as *mut libc::c_void);
|
free(invitenumber as *mut libc::c_void);
|
||||||
free(auth as *mut libc::c_void);
|
free(auth as *mut libc::c_void);
|
||||||
dc_chat_unref(chat);
|
|
||||||
free(group_name as *mut libc::c_void);
|
free(group_name as *mut libc::c_void);
|
||||||
free(group_name_urlencoded as *mut libc::c_void);
|
free(group_name_urlencoded as *mut libc::c_void);
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
|
|
||||||
if self_addr.is_none() {
|
if self_addr.is_none() {
|
||||||
error!(context, 0, "Not configured, cannot generate QR code.",);
|
error!(context, 0, "Not configured, cannot generate QR code.",);
|
||||||
return cleanup(fingerprint, chat, group_name, group_name_urlencoded);
|
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_addr = self_addr.unwrap();
|
let self_addr = self_addr.unwrap();
|
||||||
@@ -83,23 +81,15 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
fingerprint = get_self_fingerprint(context);
|
fingerprint = get_self_fingerprint(context);
|
||||||
|
|
||||||
if fingerprint.is_null() {
|
if fingerprint.is_null() {
|
||||||
return cleanup(fingerprint, chat, group_name, group_name_urlencoded);
|
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_addr_urlencoded = utf8_percent_encode(&self_addr, NON_ALPHANUMERIC).to_string();
|
let self_addr_urlencoded = utf8_percent_encode(&self_addr, NON_ALPHANUMERIC).to_string();
|
||||||
let self_name_urlencoded = utf8_percent_encode(&self_name, NON_ALPHANUMERIC).to_string();
|
let self_name_urlencoded = utf8_percent_encode(&self_name, NON_ALPHANUMERIC).to_string();
|
||||||
|
|
||||||
qr = if 0 != group_chat_id {
|
qr = if 0 != group_chat_id {
|
||||||
chat = dc_get_chat(context, group_chat_id);
|
if let Ok(chat) = dc_get_chat(context, group_chat_id) {
|
||||||
if chat.is_null() {
|
group_name = dc_chat_get_name(&chat);
|
||||||
error!(
|
|
||||||
context,
|
|
||||||
0, "Cannot get QR-code for chat-id {}", group_chat_id,
|
|
||||||
);
|
|
||||||
return cleanup(fingerprint, chat, group_name, group_name_urlencoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
group_name = dc_chat_get_name(chat);
|
|
||||||
group_name_urlencoded = dc_urlencode(group_name);
|
group_name_urlencoded = dc_urlencode(group_name);
|
||||||
|
|
||||||
Some(format!(
|
Some(format!(
|
||||||
@@ -107,10 +97,17 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
as_str(fingerprint),
|
as_str(fingerprint),
|
||||||
self_addr_urlencoded,
|
self_addr_urlencoded,
|
||||||
as_str(group_name_urlencoded),
|
as_str(group_name_urlencoded),
|
||||||
as_str((*chat).grpid),
|
as_str(chat.grpid),
|
||||||
as_str(invitenumber),
|
as_str(invitenumber),
|
||||||
as_str(auth),
|
as_str(auth),
|
||||||
))
|
))
|
||||||
|
} else {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
0, "Cannot get QR-code for chat-id {}", group_chat_id,
|
||||||
|
);
|
||||||
|
return cleanup(fingerprint, group_name, group_name_urlencoded);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"OPENPGP4FPR:{}#a={}&n={}&i={}&s={}",
|
"OPENPGP4FPR:{}#a={}&n={}&i={}&s={}",
|
||||||
@@ -124,7 +121,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
|
|
||||||
info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap());
|
info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap());
|
||||||
|
|
||||||
cleanup(fingerprint, chat, group_name, group_name_urlencoded)
|
cleanup(fingerprint, group_name, group_name_urlencoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {
|
fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {
|
||||||
|
|||||||
@@ -767,15 +767,13 @@ fn test_chat() {
|
|||||||
|
|
||||||
let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1);
|
let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1);
|
||||||
assert!(chat_id > 9, "chat_id too small {}", chat_id);
|
assert!(chat_id > 9, "chat_id too small {}", chat_id);
|
||||||
let chat = dc_chat_new(&context.ctx);
|
let chat = dc_chat_load_from_db(&context.ctx, chat_id).unwrap();
|
||||||
assert!(dc_chat_load_from_db(chat, chat_id));
|
|
||||||
|
|
||||||
let chat2_id = dc_create_chat_by_contact_id(&context.ctx, contact1);
|
let chat2_id = dc_create_chat_by_contact_id(&context.ctx, contact1);
|
||||||
assert_eq!(chat2_id, chat_id);
|
assert_eq!(chat2_id, chat_id);
|
||||||
let chat2 = dc_chat_new(&context.ctx);
|
let chat2 = dc_chat_load_from_db(&context.ctx, chat2_id).unwrap();
|
||||||
assert!(dc_chat_load_from_db(chat2, chat2_id));
|
|
||||||
|
|
||||||
assert_eq!(as_str((*chat2).name), as_str((*chat).name));
|
assert_eq!(as_str(chat2.name), as_str(chat.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user