mirror of
https://github.com/chatmail/core.git
synced 2026-05-13 20:06:30 +03:00
fix member_added/member_removed event with tests and and provide a group-tracking example
This commit is contained in:
@@ -27,7 +27,7 @@ use num_traits::{FromPrimitive, ToPrimitive};
|
|||||||
|
|
||||||
use deltachat::chat::{ChatId, ChatVisibility, MuteDuration};
|
use deltachat::chat::{ChatId, ChatVisibility, MuteDuration};
|
||||||
use deltachat::constants::DC_MSG_ID_LAST_SPECIAL;
|
use deltachat::constants::DC_MSG_ID_LAST_SPECIAL;
|
||||||
use deltachat::contact::Contact;
|
use deltachat::contact::{Contact, Origin};
|
||||||
use deltachat::context::Context;
|
use deltachat::context::Context;
|
||||||
use deltachat::key::DcKey;
|
use deltachat::key::DcKey;
|
||||||
use deltachat::message::MsgId;
|
use deltachat::message::MsgId;
|
||||||
@@ -1665,7 +1665,9 @@ pub unsafe extern "C" fn dc_lookup_contact_id_by_addr(
|
|||||||
}
|
}
|
||||||
let ffi_context = &*context;
|
let ffi_context = &*context;
|
||||||
ffi_context
|
ffi_context
|
||||||
.with_inner(|ctx| Contact::lookup_id_by_addr(ctx, to_string_lossy(addr)))
|
.with_inner(|ctx| {
|
||||||
|
Contact::lookup_id_by_addr(ctx, to_string_lossy(addr), Origin::IncomingReplyTo)
|
||||||
|
})
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
64
python/examples/group_tracking.py
Normal file
64
python/examples/group_tracking.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
# content of group_tracking.py
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import optparse
|
||||||
|
import deltachat
|
||||||
|
|
||||||
|
|
||||||
|
class GroupTrackingPlugin:
|
||||||
|
@deltachat.hookspec.account_hookimpl
|
||||||
|
def process_incoming_message(self, message):
|
||||||
|
print("*** process_incoming_message addr={} msg={!r}".format(
|
||||||
|
message.get_sender_contact().addr, message.text))
|
||||||
|
for member in message.chat.get_contacts():
|
||||||
|
print("chat member: {}".format(member.addr))
|
||||||
|
|
||||||
|
@deltachat.hookspec.account_hookimpl
|
||||||
|
def member_added(self, chat, contact):
|
||||||
|
print("*** member_added", contact.addr, "from", chat)
|
||||||
|
for member in chat.get_contacts():
|
||||||
|
print("chat member: {}".format(member.addr))
|
||||||
|
|
||||||
|
@deltachat.hookspec.account_hookimpl
|
||||||
|
def member_removed(self, chat, contact):
|
||||||
|
print("*** member_removed", contact.addr, "from", chat)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
p = optparse.OptionParser("simple-echo")
|
||||||
|
p.add_option("-l", action="store_true", help="show ffi")
|
||||||
|
p.add_option("--db", type="str", help="database file")
|
||||||
|
p.add_option("--email", type="str", help="email address")
|
||||||
|
p.add_option("--password", type="str", help="password")
|
||||||
|
|
||||||
|
opts, posargs = p.parse_args(argv)
|
||||||
|
|
||||||
|
assert opts.db, "you must specify --db"
|
||||||
|
ac = deltachat.Account(opts.db)
|
||||||
|
|
||||||
|
if opts.l:
|
||||||
|
log = deltachat.eventlogger.FFIEventLogger(ac, "group-tracking")
|
||||||
|
ac.add_account_plugin(log)
|
||||||
|
|
||||||
|
if not ac.is_configured():
|
||||||
|
assert opts.email and opts.password, (
|
||||||
|
"you must specify --email and --password"
|
||||||
|
)
|
||||||
|
ac.set_config("addr", opts.email)
|
||||||
|
ac.set_config("mail_pw", opts.password)
|
||||||
|
ac.set_config("mvbox_watch", "0")
|
||||||
|
ac.set_config("sentbox_watch", "0")
|
||||||
|
|
||||||
|
ac.add_account_plugin(GroupTrackingPlugin())
|
||||||
|
|
||||||
|
# start IO threads and configure if neccessary
|
||||||
|
ac.start()
|
||||||
|
|
||||||
|
print("{}: waiting for message".format(ac.get_config("addr")))
|
||||||
|
|
||||||
|
ac.wait_shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
||||||
@@ -173,14 +173,29 @@ class TestOfflineChat:
|
|||||||
def test_add_member_event(self, ac1):
|
def test_add_member_event(self, ac1):
|
||||||
chat = ac1.create_group_chat(name="title1")
|
chat = ac1.create_group_chat(name="title1")
|
||||||
assert chat.is_group()
|
assert chat.is_group()
|
||||||
# promote the chat
|
|
||||||
chat.send_text("hello")
|
|
||||||
contact1 = ac1.create_contact("some1@hello.com", name="some1")
|
contact1 = ac1.create_contact("some1@hello.com", name="some1")
|
||||||
|
|
||||||
chat.add_contact(contact1)
|
chat.add_contact(contact1)
|
||||||
for ev in ac1.iter_events(timeout=1):
|
for ev in ac1.iter_events(timeout=1):
|
||||||
if ev.name == "member_added":
|
if ev.name == "member_added":
|
||||||
assert ev.kwargs["chat"] == chat
|
assert ev.kwargs["chat"] == chat
|
||||||
|
if ev.kwargs["contact"] == ac1.get_self_contact():
|
||||||
|
continue
|
||||||
|
assert ev.kwargs["contact"] == contact1
|
||||||
|
break
|
||||||
|
|
||||||
|
def test_remove_member_event(self, ac1):
|
||||||
|
chat = ac1.create_group_chat(name="title1")
|
||||||
|
assert chat.is_group()
|
||||||
|
contact1 = ac1.create_contact("some1@hello.com", name="some1")
|
||||||
|
chat.add_contact(contact1)
|
||||||
|
ac1._handle_current_events()
|
||||||
|
chat.remove_contact(contact1)
|
||||||
|
for ev in ac1.iter_events(timeout=1):
|
||||||
|
if ev.name == "member_removed":
|
||||||
|
assert ev.kwargs["chat"] == chat
|
||||||
|
if ev.kwargs["contact"] == ac1.get_self_contact():
|
||||||
|
continue
|
||||||
assert ev.kwargs["contact"] == contact1
|
assert ev.kwargs["contact"] == contact1
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -471,11 +486,13 @@ class TestOfflineChat:
|
|||||||
# perform plugin hooks
|
# perform plugin hooks
|
||||||
ac1._handle_current_events()
|
ac1._handle_current_events()
|
||||||
|
|
||||||
assert len(in_list) == 10
|
assert len(in_list) == 11
|
||||||
|
chat_contacts = chat.get_contacts()
|
||||||
for in_cmd, in_chat, in_contact in in_list:
|
for in_cmd, in_chat, in_contact in in_list:
|
||||||
assert in_cmd == "added"
|
assert in_cmd == "added"
|
||||||
assert in_chat == chat
|
assert in_chat == chat
|
||||||
assert in_contact in contacts
|
assert in_contact in chat_contacts
|
||||||
|
chat_contacts.remove(in_contact)
|
||||||
|
|
||||||
lp.sec("ac1: removing two contacts and checking things are right")
|
lp.sec("ac1: removing two contacts and checking things are right")
|
||||||
chat.remove_contact(contacts[9])
|
chat.remove_contact(contacts[9])
|
||||||
@@ -483,10 +500,13 @@ class TestOfflineChat:
|
|||||||
assert len(chat.get_contacts()) == 9
|
assert len(chat.get_contacts()) == 9
|
||||||
|
|
||||||
ac1._handle_current_events()
|
ac1._handle_current_events()
|
||||||
assert len(in_list) == 12
|
assert len(in_list) == 13
|
||||||
assert in_list[-2][0] == "removed"
|
assert in_list[-2][0] == "removed"
|
||||||
assert in_list[-2][1] == chat
|
assert in_list[-2][1] == chat
|
||||||
assert in_list[-2][2] == contacts[9]
|
assert in_list[-2][2] == contacts[9]
|
||||||
|
assert in_list[-1][0] == "removed"
|
||||||
|
assert in_list[-1][1] == chat
|
||||||
|
assert in_list[-1][2] == contacts[3]
|
||||||
|
|
||||||
|
|
||||||
class TestOnlineAccount:
|
class TestOnlineAccount:
|
||||||
@@ -1259,6 +1279,51 @@ class TestOnlineAccount:
|
|||||||
msg3 = ac2._evtracker.wait_next_incoming_message()
|
msg3 = ac2._evtracker.wait_next_incoming_message()
|
||||||
assert msg3.get_sender_contact().get_profile_image() is None
|
assert msg3.get_sender_contact().get_profile_image() is None
|
||||||
|
|
||||||
|
def test_add_remove_member_remote_events(self, acfactory, lp):
|
||||||
|
ac1, ac2 = acfactory.get_two_online_accounts()
|
||||||
|
# activate local plugin for ac2
|
||||||
|
in_list = queue.Queue()
|
||||||
|
|
||||||
|
class InPlugin:
|
||||||
|
@account_hookimpl
|
||||||
|
def member_added(self, chat, contact):
|
||||||
|
in_list.put(("added", chat, contact))
|
||||||
|
|
||||||
|
@account_hookimpl
|
||||||
|
def member_removed(self, chat, contact):
|
||||||
|
in_list.put(("removed", chat, contact))
|
||||||
|
|
||||||
|
ac2.add_account_plugin(InPlugin())
|
||||||
|
|
||||||
|
lp.sec("ac1: create group chat with ac2")
|
||||||
|
chat = ac1.create_group_chat("hello")
|
||||||
|
contact = ac1.create_contact(email=ac2.get_config("addr"))
|
||||||
|
chat.add_contact(contact)
|
||||||
|
|
||||||
|
lp.sec("ac1: send a message to group chat to promote the group")
|
||||||
|
chat.send_text("afterwards promoted")
|
||||||
|
ev1 = in_list.get()
|
||||||
|
ev2 = in_list.get()
|
||||||
|
assert ev1[2] == ac2.get_self_contact()
|
||||||
|
assert ev2[2].addr == ac1.get_config("addr")
|
||||||
|
|
||||||
|
lp.sec("ac1: add address2")
|
||||||
|
contact2 = ac1.create_contact(email="not@example.org")
|
||||||
|
chat.add_contact(contact2)
|
||||||
|
ev1 = in_list.get()
|
||||||
|
assert ev1[2].addr == contact2.addr
|
||||||
|
|
||||||
|
lp.sec("ac1: remove address2")
|
||||||
|
chat.remove_contact(contact2)
|
||||||
|
ev1 = in_list.get()
|
||||||
|
assert ev1[0] == "removed"
|
||||||
|
assert ev1[2].addr == contact2.addr
|
||||||
|
|
||||||
|
lp.sec("ac1: remove ac2 contact from chat")
|
||||||
|
chat.remove_contact(contact)
|
||||||
|
ev1 = in_list.get()
|
||||||
|
assert ev1[2] == ac2.get_self_contact()
|
||||||
|
|
||||||
def test_set_get_group_image(self, acfactory, data, lp):
|
def test_set_get_group_image(self, acfactory, data, lp):
|
||||||
ac1, ac2 = acfactory.get_two_online_accounts()
|
ac1, ac2 = acfactory.get_two_online_accounts()
|
||||||
|
|
||||||
|
|||||||
55
src/chat.rs
55
src/chat.rs
@@ -1830,36 +1830,61 @@ pub fn create_group_chat(
|
|||||||
Ok(chat_id)
|
Ok(chat_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// add a contact to the chats_contact table
|
||||||
|
/// on success emit MemberAdded event and return true
|
||||||
pub(crate) fn add_to_chat_contacts_table(
|
pub(crate) fn add_to_chat_contacts_table(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
chat_id: ChatId,
|
chat_id: ChatId,
|
||||||
contact_id: u32,
|
contact_id: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// add a contact to a chat; the function does not check the type or if any of the record exist or are already
|
match sql::execute(
|
||||||
// added to the chat!
|
|
||||||
sql::execute(
|
|
||||||
context,
|
context,
|
||||||
&context.sql,
|
&context.sql,
|
||||||
"INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)",
|
"INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)",
|
||||||
params![chat_id, contact_id as i32],
|
params![chat_id, contact_id as i32],
|
||||||
)
|
) {
|
||||||
.is_ok()
|
Ok(()) => {
|
||||||
|
context.call_cb(Event::MemberAdded {
|
||||||
|
chat_id,
|
||||||
|
contact_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
"could not add {} to chat {} table: {}", contact_id, chat_id, err
|
||||||
|
);
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// remove a contact from the chats_contact table
|
||||||
|
/// on success emit MemberRemoved event and return true
|
||||||
pub(crate) fn remove_from_chat_contacts_table(
|
pub(crate) fn remove_from_chat_contacts_table(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
chat_id: ChatId,
|
chat_id: ChatId,
|
||||||
contact_id: u32,
|
contact_id: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// remove a contact from the chats_contact table unconditionally
|
match sql::execute(
|
||||||
// the function does not check the type or if the record exist
|
|
||||||
sql::execute(
|
|
||||||
context,
|
context,
|
||||||
&context.sql,
|
&context.sql,
|
||||||
"DELETE FROM chats_contacts WHERE chat_id=? AND contact_id=?",
|
"DELETE FROM chats_contacts WHERE chat_id=? AND contact_id=?",
|
||||||
params![chat_id, contact_id as i32],
|
params![chat_id, contact_id as i32],
|
||||||
)
|
) {
|
||||||
.is_ok()
|
Ok(()) => {
|
||||||
|
context.call_cb(Event::MemberRemoved {
|
||||||
|
chat_id,
|
||||||
|
contact_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a contact to the chat.
|
/// Adds a contact to the chat.
|
||||||
@@ -1955,12 +1980,6 @@ pub(crate) fn add_contact_to_chat_ex(
|
|||||||
msg.param.set_int(Param::Arg2, from_handshake.into());
|
msg.param.set_int(Param::Arg2, from_handshake.into());
|
||||||
|
|
||||||
msg.id = send_msg(context, chat_id, &mut msg)?;
|
msg.id = send_msg(context, chat_id, &mut msg)?;
|
||||||
// send_msg sends MsgsChanged event
|
|
||||||
// so we only send an explicit MemberAdded one
|
|
||||||
context.call_cb(Event::MemberAdded {
|
|
||||||
chat_id,
|
|
||||||
contact_id: contact.id,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// send an event for unpromoted groups
|
// send an event for unpromoted groups
|
||||||
// XXX probably not neccessary because ChatModified should suffice
|
// XXX probably not neccessary because ChatModified should suffice
|
||||||
@@ -2173,10 +2192,6 @@ pub fn remove_contact_from_chat(
|
|||||||
msg.param.set_cmd(SystemMessage::MemberRemovedFromGroup);
|
msg.param.set_cmd(SystemMessage::MemberRemovedFromGroup);
|
||||||
msg.param.set(Param::Arg, contact.get_addr());
|
msg.param.set(Param::Arg, contact.get_addr());
|
||||||
msg.id = send_msg(context, chat_id, &mut msg)?;
|
msg.id = send_msg(context, chat_id, &mut msg)?;
|
||||||
context.call_cb(Event::MemberRemoved {
|
|
||||||
chat_id,
|
|
||||||
contact_id: contact.id,
|
|
||||||
});
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.call_cb(Event::MsgsChanged {
|
||||||
chat_id,
|
chat_id,
|
||||||
msg_id: msg.id,
|
msg_id: msg.id,
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ use crate::peerstate::*;
|
|||||||
use crate::sql;
|
use crate::sql;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
|
||||||
/// Contacts with at least this origin value are shown in the contact list.
|
|
||||||
const DC_ORIGIN_MIN_CONTACT_LIST: i32 = 0x100;
|
|
||||||
|
|
||||||
/// An object representing a single contact in memory.
|
/// An object representing a single contact in memory.
|
||||||
///
|
///
|
||||||
/// The contact object is not updated.
|
/// The contact object is not updated.
|
||||||
@@ -94,6 +91,7 @@ pub enum Origin {
|
|||||||
UnhandledQrScan = 0x80,
|
UnhandledQrScan = 0x80,
|
||||||
|
|
||||||
/// Reply-To: of incoming message of known sender
|
/// Reply-To: of incoming message of known sender
|
||||||
|
/// Contacts with at least this origin value are shown in the contact list.
|
||||||
IncomingReplyTo = 0x100,
|
IncomingReplyTo = 0x100,
|
||||||
|
|
||||||
/// Cc: of incoming message of known sender
|
/// Cc: of incoming message of known sender
|
||||||
@@ -274,7 +272,7 @@ impl Contact {
|
|||||||
///
|
///
|
||||||
/// To validate an e-mail address independently of the contact database
|
/// To validate an e-mail address independently of the contact database
|
||||||
/// use `dc_may_be_valid_addr()`.
|
/// use `dc_may_be_valid_addr()`.
|
||||||
pub fn lookup_id_by_addr(context: &Context, addr: impl AsRef<str>) -> u32 {
|
pub fn lookup_id_by_addr(context: &Context, addr: impl AsRef<str>, min_origin: Origin) -> u32 {
|
||||||
if addr.as_ref().is_empty() {
|
if addr.as_ref().is_empty() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -287,14 +285,13 @@ impl Contact {
|
|||||||
if addr_cmp(addr_normalized, addr_self) {
|
if addr_cmp(addr_normalized, addr_self) {
|
||||||
return DC_CONTACT_ID_SELF;
|
return DC_CONTACT_ID_SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sql.query_get_value(
|
context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;",
|
"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;",
|
||||||
params![
|
params![
|
||||||
addr_normalized,
|
addr_normalized,
|
||||||
DC_CONTACT_ID_LAST_SPECIAL as i32,
|
DC_CONTACT_ID_LAST_SPECIAL as i32,
|
||||||
DC_ORIGIN_MIN_CONTACT_LIST,
|
min_origin as u32,
|
||||||
],
|
],
|
||||||
).unwrap_or_default()
|
).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -800,7 +800,6 @@ fn create_or_lookup_group(
|
|||||||
let mut chat_id_blocked = Blocked::Not;
|
let mut chat_id_blocked = Blocked::Not;
|
||||||
let mut recreate_member_list = false;
|
let mut recreate_member_list = false;
|
||||||
let mut send_EVENT_CHAT_MODIFIED = false;
|
let mut send_EVENT_CHAT_MODIFIED = false;
|
||||||
let mut X_MrRemoveFromGrp = None;
|
|
||||||
let mut X_MrAddToGrp = None;
|
let mut X_MrAddToGrp = None;
|
||||||
let mut X_MrGrpNameChanged = false;
|
let mut X_MrGrpNameChanged = false;
|
||||||
let mut better_msg: String = From::from("");
|
let mut better_msg: String = From::from("");
|
||||||
@@ -848,22 +847,25 @@ fn create_or_lookup_group(
|
|||||||
// but we might not know about this group
|
// but we might not know about this group
|
||||||
|
|
||||||
let grpname = mime_parser.get(HeaderDef::ChatGroupName).cloned();
|
let grpname = mime_parser.get(HeaderDef::ChatGroupName).cloned();
|
||||||
|
let mut removed_id = 0;
|
||||||
|
|
||||||
if let Some(optional_field) = mime_parser.get(HeaderDef::ChatGroupMemberRemoved).cloned() {
|
if let Some(removed_addr) = mime_parser.get(HeaderDef::ChatGroupMemberRemoved).cloned() {
|
||||||
X_MrRemoveFromGrp = Some(optional_field);
|
removed_id = Contact::lookup_id_by_addr(context, &removed_addr, Origin::Unknown);
|
||||||
mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup;
|
if removed_id == 0 {
|
||||||
let left_group = Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap())
|
warn!(context, "removed {:?} has no contact_id", removed_addr);
|
||||||
== from_id as u32;
|
} else {
|
||||||
better_msg = context.stock_system_msg(
|
mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup;
|
||||||
if left_group {
|
better_msg = context.stock_system_msg(
|
||||||
StockMessage::MsgGroupLeft
|
if removed_id == from_id as u32 {
|
||||||
} else {
|
StockMessage::MsgGroupLeft
|
||||||
StockMessage::MsgDelMember
|
} else {
|
||||||
},
|
StockMessage::MsgDelMember
|
||||||
X_MrRemoveFromGrp.as_ref().unwrap(),
|
},
|
||||||
"",
|
&removed_addr,
|
||||||
from_id as u32,
|
"",
|
||||||
)
|
from_id as u32,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let field = mime_parser.get(HeaderDef::ChatGroupMemberAdded).cloned();
|
let field = mime_parser.get(HeaderDef::ChatGroupMemberAdded).cloned();
|
||||||
if let Some(optional_field) = field {
|
if let Some(optional_field) = field {
|
||||||
@@ -949,7 +951,7 @@ fn create_or_lookup_group(
|
|||||||
&& !grpid.is_empty()
|
&& !grpid.is_empty()
|
||||||
&& grpname.is_some()
|
&& grpname.is_some()
|
||||||
// otherwise, a pending "quit" message may pop up
|
// otherwise, a pending "quit" message may pop up
|
||||||
&& X_MrRemoveFromGrp.is_none()
|
&& removed_id == 0
|
||||||
// re-create explicitly left groups only if ourself is re-added
|
// re-create explicitly left groups only if ourself is re-added
|
||||||
&& (!group_explicitly_left
|
&& (!group_explicitly_left
|
||||||
|| X_MrAddToGrp.is_some() && addr_cmp(&self_addr, X_MrAddToGrp.as_ref().unwrap()))
|
|| X_MrAddToGrp.is_some() && addr_cmp(&self_addr, X_MrAddToGrp.as_ref().unwrap()))
|
||||||
@@ -1083,12 +1085,8 @@ fn create_or_lookup_group(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_EVENT_CHAT_MODIFIED = true;
|
send_EVENT_CHAT_MODIFIED = true;
|
||||||
} else if let Some(removed_addr) = X_MrRemoveFromGrp {
|
} else if removed_id > 0 {
|
||||||
let contact_id = Contact::lookup_id_by_addr(context, removed_addr);
|
chat::remove_from_chat_contacts_table(context, chat_id, removed_id);
|
||||||
if contact_id != 0 {
|
|
||||||
info!(context, "remove {:?} from chat id={}", contact_id, chat_id);
|
|
||||||
chat::remove_from_chat_contacts_table(context, chat_id, contact_id);
|
|
||||||
}
|
|
||||||
send_EVENT_CHAT_MODIFIED = true;
|
send_EVENT_CHAT_MODIFIED = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ impl Context {
|
|||||||
from_id: u32,
|
from_id: u32,
|
||||||
) -> String {
|
) -> String {
|
||||||
let insert1 = if id == StockMessage::MsgAddMember || id == StockMessage::MsgDelMember {
|
let insert1 = if id == StockMessage::MsgAddMember || id == StockMessage::MsgDelMember {
|
||||||
let contact_id = Contact::lookup_id_by_addr(self, param1.as_ref());
|
let contact_id = Contact::lookup_id_by_addr(self, param1.as_ref(), Origin::Unknown);
|
||||||
if contact_id != 0 {
|
if contact_id != 0 {
|
||||||
Contact::get_by_id(self, contact_id)
|
Contact::get_by_id(self, contact_id)
|
||||||
.map(|contact| contact.get_name_n_addr())
|
.map(|contact| contact.get_name_n_addr())
|
||||||
|
|||||||
Reference in New Issue
Block a user