mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 01:16:31 +03:00
feat: use EventEmitter for events
This commit is contained in:
committed by
GitHub
parent
4b4e6e1732
commit
014d2946b2
@@ -57,14 +57,15 @@ image = { version = "0.22.4", default-features=false, features = ["gif_codec", "
|
|||||||
futures = "0.3.4"
|
futures = "0.3.4"
|
||||||
thiserror = "1.0.14"
|
thiserror = "1.0.14"
|
||||||
anyhow = "1.0.28"
|
anyhow = "1.0.28"
|
||||||
|
async-trait = "0.1.31"
|
||||||
|
url = "2.1.1"
|
||||||
|
crossbeam-channel = "0.4.2"
|
||||||
|
|
||||||
pretty_env_logger = { version = "0.3.1", optional = true }
|
pretty_env_logger = { version = "0.3.1", optional = true }
|
||||||
log = {version = "0.4.8", optional = true }
|
log = {version = "0.4.8", optional = true }
|
||||||
rustyline = { version = "4.1.0", optional = true }
|
rustyline = { version = "4.1.0", optional = true }
|
||||||
ansi_term = { version = "0.12.1", optional = true }
|
ansi_term = { version = "0.12.1", optional = true }
|
||||||
async-trait = "0.1.31"
|
|
||||||
crossbeam-channel = "0.4.2"
|
|
||||||
url = "2.1.1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
@@ -95,3 +96,4 @@ internals = []
|
|||||||
repl = ["internals", "rustyline", "log", "pretty_env_logger", "ansi_term"]
|
repl = ["internals", "rustyline", "log", "pretty_env_logger", "ansi_term"]
|
||||||
vendored = ["async-native-tls/vendored", "async-smtp/native-tls-vendored"]
|
vendored = ["async-native-tls/vendored", "async-smtp/native-tls-vendored"]
|
||||||
nightly = ["pgp/nightly"]
|
nightly = ["pgp/nightly"]
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ typedef struct _dc_contact dc_contact_t;
|
|||||||
typedef struct _dc_lot dc_lot_t;
|
typedef struct _dc_lot dc_lot_t;
|
||||||
typedef struct _dc_provider dc_provider_t;
|
typedef struct _dc_provider dc_provider_t;
|
||||||
typedef struct _dc_event dc_event_t;
|
typedef struct _dc_event dc_event_t;
|
||||||
|
typedef struct _dc_event_emitter dc_event_emitter_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,7 +194,10 @@ typedef struct _dc_event dc_event_t;
|
|||||||
/**
|
/**
|
||||||
* TODO: document
|
* TODO: document
|
||||||
*/
|
*/
|
||||||
dc_event_t* dc_get_next_event(dc_context_t* context);
|
dc_event_t* dc_get_next_event(dc_event_emitter_t* emitter);
|
||||||
|
|
||||||
|
dc_event_emitter_t* dc_get_event_emitter(dc_context_t* context);
|
||||||
|
void dc_event_emitter_unref(dc_event_emitter_t* emitter);
|
||||||
|
|
||||||
int dc_event_get_id (dc_event_t* event);
|
int dc_event_get_id (dc_event_t* event);
|
||||||
int dc_event_get_data1_int(dc_event_t* event);
|
int dc_event_get_data1_int(dc_event_t* event);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ impl ContextWrapper {
|
|||||||
/// logfile rather than being shown directly to the user.
|
/// logfile rather than being shown directly to the user.
|
||||||
unsafe fn warning(&self, msg: &str) {
|
unsafe fn warning(&self, msg: &str) {
|
||||||
self.with_inner(|ctx| {
|
self.with_inner(|ctx| {
|
||||||
ctx.call_cb(Event::Warning(msg.to_string()));
|
ctx.emit_event(Event::Warning(msg.to_string()));
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@@ -650,20 +650,45 @@ pub unsafe extern "C" fn dc_event_get_data3_str(event: *mut dc_event_t) -> *mut
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_get_next_event(context: *mut dc_context_t) -> *mut dc_event_t {
|
pub type dc_event_emitter_t = EventEmitter;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_get_event_emitter(
|
||||||
|
context: *mut dc_context_t,
|
||||||
|
) -> *mut dc_event_emitter_t {
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
|
eprintln!("ignoring careless call to dc_get_event_emitter()");
|
||||||
return ptr::null_mut();
|
return ptr::null_mut();
|
||||||
}
|
}
|
||||||
let ffi_context = &*context;
|
let ffi_context = &*context;
|
||||||
|
|
||||||
ffi_context
|
ffi_context
|
||||||
.with_inner(|ctx| match ctx.get_next_event() {
|
.with_inner(|ctx| Box::into_raw(Box::new(ctx.get_event_emitter())))
|
||||||
Ok(ev) => Box::into_raw(Box::new(ev)),
|
|
||||||
Err(_) => ptr::null_mut(),
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|_| ptr::null_mut())
|
.unwrap_or_else(|_| ptr::null_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_event_emitter_unref(emitter: *mut dc_event_emitter_t) {
|
||||||
|
if emitter.is_null() {
|
||||||
|
eprintln!("ignoring careless call to dc_event_mitter_unref()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::from_raw(emitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_get_next_event(events: *mut dc_event_emitter_t) -> *mut dc_event_t {
|
||||||
|
if events.is_null() {
|
||||||
|
return ptr::null_mut();
|
||||||
|
}
|
||||||
|
let events = &*events;
|
||||||
|
|
||||||
|
events
|
||||||
|
.recv_sync()
|
||||||
|
.map(|ev| Box::into_raw(Box::new(ev)))
|
||||||
|
.unwrap_or_else(|| ptr::null_mut())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_stop_io(context: *mut dc_context_t) {
|
pub unsafe extern "C" fn dc_stop_io(context: *mut dc_context_t) {
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ async fn reset_tables(context: &Context, bits: i32) {
|
|||||||
println!("(8) Rest but server config reset.");
|
println!("(8) Rest but server config reset.");
|
||||||
}
|
}
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -157,7 +157,7 @@ async fn poke_spec(context: &Context, spec: Option<&str>) -> bool {
|
|||||||
}
|
}
|
||||||
println!("Import: {} items read from \"{}\".", read_cnt, &real_spec);
|
println!("Import: {} items read from \"{}\".", read_cnt, &real_spec);
|
||||||
if read_cnt > 0 {
|
if read_cnt > 0 {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1030,7 +1030,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
// ensure!(!arg1.is_empty(), "Argument <id> missing.");
|
// ensure!(!arg1.is_empty(), "Argument <id> missing.");
|
||||||
// let event = arg1.parse()?;
|
// let event = arg1.parse()?;
|
||||||
// let event = Event::from_u32(event).ok_or(format_err!("Event::from_u32({})", event))?;
|
// let event = Event::from_u32(event).ok_or(format_err!("Event::from_u32({})", event))?;
|
||||||
// let r = context.call_cb(event, 0 as libc::uintptr_t, 0 as libc::uintptr_t);
|
// let r = context.emit_event(event, 0 as libc::uintptr_t, 0 as libc::uintptr_t);
|
||||||
// println!(
|
// println!(
|
||||||
// "Sending event {:?}({}), received value {}.",
|
// "Sending event {:?}({}), received value {}.",
|
||||||
// event, event as usize, r as libc::c_int,
|
// event, event as usize, r as libc::c_int,
|
||||||
|
|||||||
@@ -275,10 +275,10 @@ async fn start(args: Vec<String>) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
let context = Context::new("CLI".into(), Path::new(&args[1]).to_path_buf()).await?;
|
let context = Context::new("CLI".into(), Path::new(&args[1]).to_path_buf()).await?;
|
||||||
|
|
||||||
let ctx = context.clone();
|
let events = context.get_event_emitter();
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
if let Ok(event) = ctx.get_next_event() {
|
if let Some(event) = events.recv().await {
|
||||||
receive_event(event);
|
receive_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ async fn main() {
|
|||||||
let duration = time::Duration::from_millis(4000);
|
let duration = time::Duration::from_millis(4000);
|
||||||
println!("info: {:#?}", info);
|
println!("info: {:#?}", info);
|
||||||
|
|
||||||
let ctx1 = ctx.clone();
|
let events = ctx.get_event_emitter();
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
if let Ok(event) = ctx1.get_next_event() {
|
if let Some(event) = events.recv().await {
|
||||||
cb(event);
|
cb(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -613,24 +613,23 @@ class Account(object):
|
|||||||
else:
|
else:
|
||||||
self.log("stop_scheduler called on non-running context")
|
self.log("stop_scheduler called on non-running context")
|
||||||
|
|
||||||
def shutdown(self, wait=True):
|
def shutdown(self):
|
||||||
""" shutdown and destroy account (stop callback thread, close and remove
|
""" shutdown and destroy account (stop callback thread, close and remove
|
||||||
underlying dc_context."""
|
underlying dc_context)."""
|
||||||
dc_context = self._dc_context
|
dc_context = self._dc_context
|
||||||
if dc_context is None:
|
if dc_context is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._event_thread.is_alive():
|
|
||||||
self.log("stop threads")
|
|
||||||
self._event_thread.stop(wait=False)
|
|
||||||
|
|
||||||
self.stop_scheduler()
|
self.stop_scheduler()
|
||||||
|
|
||||||
self.log("dc_close")
|
self.log("dc_close")
|
||||||
|
# the dc_close triggers get_next_event to return ffi.NULL
|
||||||
|
# which in turns makes the event thread finish execution
|
||||||
lib.dc_close(dc_context)
|
lib.dc_close(dc_context)
|
||||||
self.log("wait threads for real")
|
|
||||||
if wait:
|
self.log("wait for event thread to finish")
|
||||||
self._event_thread.stop(wait=wait)
|
self._event_thread.wait()
|
||||||
|
|
||||||
self._dc_context = None
|
self._dc_context = None
|
||||||
atexit.unregister(self.shutdown)
|
atexit.unregister(self.shutdown)
|
||||||
self._shutdown_event.set()
|
self._shutdown_event.set()
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ class EventThread(threading.Thread):
|
|||||||
def __init__(self, account):
|
def __init__(self, account):
|
||||||
self.account = account
|
self.account = account
|
||||||
self._dc_context = account._dc_context
|
self._dc_context = account._dc_context
|
||||||
self._thread_quitflag = False
|
|
||||||
super(EventThread, self).__init__(name="events")
|
super(EventThread, self).__init__(name="events")
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
@@ -144,15 +143,12 @@ class EventThread(threading.Thread):
|
|||||||
yield
|
yield
|
||||||
self.account.log(message + " FINISHED")
|
self.account.log(message + " FINISHED")
|
||||||
|
|
||||||
def stop(self, wait=False):
|
def wait(self):
|
||||||
self._thread_quitflag = True
|
if self == threading.current_thread():
|
||||||
|
# we are in the callback thread and thus cannot
|
||||||
if wait:
|
# wait for the thread-loop to finish.
|
||||||
if self == threading.current_thread():
|
return
|
||||||
# we are in the callback thread and thus cannot
|
self.join()
|
||||||
# wait for the thread-loop to finish.
|
|
||||||
return
|
|
||||||
self.join()
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
""" get and run events until shutdown. """
|
""" get and run events until shutdown. """
|
||||||
@@ -160,8 +156,12 @@ class EventThread(threading.Thread):
|
|||||||
self._inner_run()
|
self._inner_run()
|
||||||
|
|
||||||
def _inner_run(self):
|
def _inner_run(self):
|
||||||
while lib.dc_is_open(self._dc_context) and not self._thread_quitflag:
|
event_emitter = ffi.gc(
|
||||||
event = lib.dc_get_next_event(self._dc_context)
|
lib.dc_get_event_emitter(self._dc_context),
|
||||||
|
lib.dc_event_emitter_unref,
|
||||||
|
)
|
||||||
|
while 1:
|
||||||
|
event = lib.dc_get_next_event(event_emitter)
|
||||||
if event == ffi.NULL:
|
if event == ffi.NULL:
|
||||||
break
|
break
|
||||||
evt = lib.dc_event_get_id(event)
|
evt = lib.dc_event_get_id(event)
|
||||||
@@ -180,14 +180,7 @@ class EventThread(threading.Thread):
|
|||||||
for name, kwargs in self._map_ffi_event(ffi_event):
|
for name, kwargs in self._map_ffi_event(ffi_event):
|
||||||
# self.account.log("calling hook name={} kwargs={}".format(name, kwargs))
|
# self.account.log("calling hook name={} kwargs={}".format(name, kwargs))
|
||||||
hook = getattr(self.account._pm.hook, name)
|
hook = getattr(self.account._pm.hook, name)
|
||||||
try:
|
hook(**kwargs)
|
||||||
hook(**kwargs)
|
|
||||||
except Exception:
|
|
||||||
# don't bother logging this error
|
|
||||||
# if dc_close() was concurrently called
|
|
||||||
# (note: core API starts failing after that)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def _map_ffi_event(self, ffi_event):
|
def _map_ffi_event(self, ffi_event):
|
||||||
name = ffi_event.name
|
name = ffi_event.name
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl<'a> BlobObject<'a> {
|
|||||||
blobdir,
|
blobdir,
|
||||||
name: format!("$BLOBDIR/{}", name),
|
name: format!("$BLOBDIR/{}", name),
|
||||||
};
|
};
|
||||||
context.call_cb(Event::NewBlobFile(blob.as_name().to_string()));
|
context.emit_event(Event::NewBlobFile(blob.as_name().to_string()));
|
||||||
Ok(blob)
|
Ok(blob)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ impl<'a> BlobObject<'a> {
|
|||||||
blobdir: context.get_blobdir(),
|
blobdir: context.get_blobdir(),
|
||||||
name: format!("$BLOBDIR/{}", name),
|
name: format!("$BLOBDIR/{}", name),
|
||||||
};
|
};
|
||||||
context.call_cb(Event::NewBlobFile(blob.as_name().to_string()));
|
context.emit_event(Event::NewBlobFile(blob.as_name().to_string()));
|
||||||
Ok(blob)
|
Ok(blob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
src/chat.rs
40
src/chat.rs
@@ -174,7 +174,7 @@ impl ChatId {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
@@ -231,7 +231,7 @@ impl ChatId {
|
|||||||
.execute("DELETE FROM chats WHERE id=?;", paramsv![self])
|
.execute("DELETE FROM chats WHERE id=?;", paramsv![self])
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
@@ -256,7 +256,7 @@ impl ChatId {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if changed {
|
if changed {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: self,
|
chat_id: self,
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1098,7 +1098,7 @@ pub async fn create_by_msg_id(context: &Context, msg_id: MsgId) -> Result<ChatId
|
|||||||
chat.id.unblock(context).await;
|
chat.id.unblock(context).await;
|
||||||
|
|
||||||
// Sending with 0s as data since multiple messages may have changed.
|
// Sending with 0s as data since multiple messages may have changed.
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1140,7 +1140,7 @@ pub async fn create_by_contact_id(context: &Context, contact_id: u32) -> Result<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1307,7 +1307,7 @@ pub async fn prepare_msg(
|
|||||||
|
|
||||||
msg.state = MessageState::OutPreparing;
|
msg.state = MessageState::OutPreparing;
|
||||||
let msg_id = prepare_msg_common(context, chat_id, msg).await?;
|
let msg_id = prepare_msg_common(context, chat_id, msg).await?;
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: msg.chat_id,
|
chat_id: msg.chat_id,
|
||||||
msg_id: msg.id,
|
msg_id: msg.id,
|
||||||
});
|
});
|
||||||
@@ -1476,13 +1476,13 @@ async fn send_msg_inner(
|
|||||||
}
|
}
|
||||||
job::send_msg(context, msg.id).await?;
|
job::send_msg(context, msg.id).await?;
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: msg.chat_id,
|
chat_id: msg.chat_id,
|
||||||
msg_id: msg.id,
|
msg_id: msg.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if msg.param.exists(Param::SetLatitude) {
|
if msg.param.exists(Param::SetLatitude) {
|
||||||
context.call_cb(Event::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
context.emit_event(Event::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(msg.id)
|
Ok(msg.id)
|
||||||
@@ -1514,7 +1514,7 @@ pub async fn get_chat_msgs(
|
|||||||
Err(err) => warn!(context, "Failed to delete expired messages: {}", err),
|
Err(err) => warn!(context, "Failed to delete expired messages: {}", err),
|
||||||
Ok(messages_deleted) => {
|
Ok(messages_deleted) => {
|
||||||
if messages_deleted {
|
if messages_deleted {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
})
|
})
|
||||||
@@ -1635,7 +1635,7 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<(),
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1667,7 +1667,7 @@ pub async fn marknoticed_all_chats(context: &Context) -> Result<(), Error> {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1884,7 +1884,7 @@ pub async fn create_group_chat(
|
|||||||
chat_id.set_draft_raw(context, &mut draft_msg).await;
|
chat_id.set_draft_raw(context, &mut draft_msg).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
@@ -2043,7 +2043,7 @@ pub(crate) async 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).await?;
|
msg.id = send_msg(context, chat_id, &mut msg).await?;
|
||||||
}
|
}
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2205,7 +2205,7 @@ pub async fn set_muted(
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
} else {
|
} else {
|
||||||
bail!("Failed to set mute duration, chat might not exist -");
|
bail!("Failed to set mute duration, chat might not exist -");
|
||||||
}
|
}
|
||||||
@@ -2285,7 +2285,7 @@ pub async fn remove_contact_from_chat(
|
|||||||
// removed it first, it would complicate the
|
// removed it first, it would complicate the
|
||||||
// check/encryption logic.
|
// check/encryption logic.
|
||||||
success = remove_from_chat_contacts_table(context, chat_id, contact_id).await;
|
success = remove_from_chat_contacts_table(context, chat_id, contact_id).await;
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2375,12 +2375,12 @@ pub async fn set_chat_name(
|
|||||||
msg.param.set(Param::Arg, &chat.name);
|
msg.param.set(Param::Arg, &chat.name);
|
||||||
}
|
}
|
||||||
msg.id = send_msg(context, chat_id, &mut msg).await?;
|
msg.id = send_msg(context, chat_id, &mut msg).await?;
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id,
|
chat_id,
|
||||||
msg_id: msg.id,
|
msg_id: msg.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2540,7 +2540,7 @@ pub async fn forward_msgs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (chat_id, msg_id) in created_chats.iter().zip(created_msgs.iter()) {
|
for (chat_id, msg_id) in created_chats.iter().zip(created_msgs.iter()) {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: *chat_id,
|
chat_id: *chat_id,
|
||||||
msg_id: *msg_id,
|
msg_id: *msg_id,
|
||||||
});
|
});
|
||||||
@@ -2663,7 +2663,7 @@ pub async fn add_device_msg(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !msg_id.is_unset() {
|
if !msg_id.is_unset() {
|
||||||
context.call_cb(Event::IncomingMsg { chat_id, msg_id });
|
context.emit_event(Event::IncomingMsg { chat_id, msg_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(msg_id)
|
Ok(msg_id)
|
||||||
@@ -2733,7 +2733,7 @@ pub(crate) async fn add_info_msg(context: &Context, chat_id: ChatId, text: impl
|
|||||||
.get_rowid(context, "msgs", "rfc724_mid", &rfc724_mid)
|
.get_rowid(context, "msgs", "rfc724_mid", &rfc724_mid)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id,
|
chat_id,
|
||||||
msg_id: MsgId::new(row_id),
|
msg_id: MsgId::new(row_id),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ impl Context {
|
|||||||
Config::DeleteDeviceAfter => {
|
Config::DeleteDeviceAfter => {
|
||||||
let ret = self.sql.set_raw_config(self, key, value).await;
|
let ret = self.sql.set_raw_config(self, key, value).await;
|
||||||
// Force chatlist reload to delete old messages immediately.
|
// Force chatlist reload to delete old messages immediately.
|
||||||
self.call_cb(Event::MsgsChanged {
|
self.emit_event(Event::MsgsChanged {
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ macro_rules! progress {
|
|||||||
$progress <= 1000,
|
$progress <= 1000,
|
||||||
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
||||||
);
|
);
|
||||||
$context.call_cb($crate::events::Event::ConfigureProgress($progress));
|
$context.emit_event($crate::events::Event::ConfigureProgress($progress));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ impl Contact {
|
|||||||
let (contact_id, sth_modified) =
|
let (contact_id, sth_modified) =
|
||||||
Contact::add_or_lookup(context, name, addr, Origin::ManuallyCreated).await?;
|
Contact::add_or_lookup(context, name, addr, Origin::ManuallyCreated).await?;
|
||||||
let blocked = Contact::is_blocked_load(context, contact_id).await;
|
let blocked = Contact::is_blocked_load(context, contact_id).await;
|
||||||
context.call_cb(Event::ContactsChanged(
|
context.emit_event(Event::ContactsChanged(
|
||||||
if sth_modified == Modifier::Created {
|
if sth_modified == Modifier::Created {
|
||||||
Some(contact_id)
|
Some(contact_id)
|
||||||
} else {
|
} else {
|
||||||
@@ -269,7 +269,7 @@ impl Contact {
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -528,7 +528,7 @@ impl Contact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modify_cnt > 0 {
|
if modify_cnt > 0 {
|
||||||
context.call_cb(Event::ContactsChanged(None));
|
context.emit_event(Event::ContactsChanged(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(modify_cnt)
|
Ok(modify_cnt)
|
||||||
@@ -777,7 +777,7 @@ impl Contact {
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
context.call_cb(Event::ContactsChanged(None));
|
context.emit_event(Event::ContactsChanged(None));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -1054,7 +1054,7 @@ async fn set_block_contact(context: &Context, contact_id: u32, new_blocking: boo
|
|||||||
paramsv![new_blocking, 100, contact_id as i32],
|
paramsv![new_blocking, 100, contact_id as i32],
|
||||||
).await.is_ok() {
|
).await.is_ok() {
|
||||||
Contact::mark_noticed(context, contact_id).await;
|
Contact::mark_noticed(context, contact_id).await;
|
||||||
context.call_cb(Event::ContactsChanged(None));
|
context.emit_event(Event::ContactsChanged(None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1080,7 @@ pub(crate) async fn set_profile_image(
|
|||||||
};
|
};
|
||||||
if changed {
|
if changed {
|
||||||
contact.update_param(context).await?;
|
contact.update_param(context).await?;
|
||||||
context.call_cb(Event::ContactsChanged(Some(contact_id)));
|
context.emit_event(Event::ContactsChanged(Some(contact_id)));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ use std::collections::{BTreeMap, HashMap};
|
|||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
|
||||||
use async_std::path::{Path, PathBuf};
|
use async_std::path::{Path, PathBuf};
|
||||||
use async_std::sync::{channel, Arc, Mutex, Receiver, RwLock, Sender};
|
use async_std::sync::{channel, Arc, Mutex, Receiver, RwLock, Sender};
|
||||||
use crossbeam_channel::{unbounded, Receiver as SyncReceiver, Sender as SyncSender};
|
|
||||||
|
|
||||||
use crate::chat::*;
|
use crate::chat::*;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
@@ -15,7 +13,7 @@ use crate::constants::*;
|
|||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::dc_tools::duration_to_str;
|
use crate::dc_tools::duration_to_str;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::events::Event;
|
use crate::events::{Event, EventEmitter, Events};
|
||||||
use crate::job::{self, Action};
|
use crate::job::{self, Action};
|
||||||
use crate::key::{DcKey, Key, SignedPublicKey};
|
use crate::key::{DcKey, Key, SignedPublicKey};
|
||||||
use crate::login_param::LoginParam;
|
use crate::login_param::LoginParam;
|
||||||
@@ -55,7 +53,7 @@ pub struct InnerContext {
|
|||||||
/// Mutex to enforce only a single running oauth2 is running.
|
/// Mutex to enforce only a single running oauth2 is running.
|
||||||
pub(crate) oauth2_mutex: Mutex<()>,
|
pub(crate) oauth2_mutex: Mutex<()>,
|
||||||
pub(crate) translated_stockstrings: RwLock<HashMap<usize, String>>,
|
pub(crate) translated_stockstrings: RwLock<HashMap<usize, String>>,
|
||||||
pub(crate) logs: (SyncSender<Event>, SyncReceiver<Event>),
|
pub(crate) events: Events,
|
||||||
|
|
||||||
pub(crate) scheduler: RwLock<Scheduler>,
|
pub(crate) scheduler: RwLock<Scheduler>,
|
||||||
|
|
||||||
@@ -121,7 +119,7 @@ impl Context {
|
|||||||
generating_key_mutex: Mutex::new(()),
|
generating_key_mutex: Mutex::new(()),
|
||||||
oauth2_mutex: Mutex::new(()),
|
oauth2_mutex: Mutex::new(()),
|
||||||
translated_stockstrings: RwLock::new(HashMap::new()),
|
translated_stockstrings: RwLock::new(HashMap::new()),
|
||||||
logs: unbounded(),
|
events: Events::default(),
|
||||||
scheduler: RwLock::new(Scheduler::Stopped),
|
scheduler: RwLock::new(Scheduler::Stopped),
|
||||||
creation_time: std::time::SystemTime::now(),
|
creation_time: std::time::SystemTime::now(),
|
||||||
};
|
};
|
||||||
@@ -172,14 +170,14 @@ impl Context {
|
|||||||
self.blobdir.as_path()
|
self.blobdir.as_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_cb(&self, event: Event) {
|
/// Emits a single event.
|
||||||
self.logs.0.send(event).expect("failed to send event");
|
pub fn emit_event(&self, event: Event) {
|
||||||
|
self.events.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_next_event(&self) -> Result<Event> {
|
/// Get the next queued event.
|
||||||
let event = self.logs.1.recv().map_err(|err| anyhow!("{}", err))?;
|
pub fn get_event_emitter(&self) -> EventEmitter {
|
||||||
|
self.events.get_emitter()
|
||||||
Ok(event)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ongoing process allocation/free/check
|
// Ongoing process allocation/free/check
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ pub async fn dc_receive_imf(
|
|||||||
CreateEvent::MsgsChanged => Event::MsgsChanged { msg_id, chat_id },
|
CreateEvent::MsgsChanged => Event::MsgsChanged { msg_id, chat_id },
|
||||||
CreateEvent::IncomingMsg => Event::IncomingMsg { msg_id, chat_id },
|
CreateEvent::IncomingMsg => Event::IncomingMsg { msg_id, chat_id },
|
||||||
};
|
};
|
||||||
context.call_cb(event);
|
context.emit_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -197,7 +197,7 @@ pub async fn dc_receive_imf(
|
|||||||
if let Some(avatar_action) = &mime_parser.user_avatar {
|
if let Some(avatar_action) = &mime_parser.user_avatar {
|
||||||
match contact::set_profile_image(&context, from_id, avatar_action).await {
|
match contact::set_profile_image(&context, from_id, avatar_action).await {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(context, "reveive_imf cannot update profile image: {}", err);
|
warn!(context, "reveive_imf cannot update profile image: {}", err);
|
||||||
@@ -806,7 +806,7 @@ async fn save_locations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if send_event {
|
if send_event {
|
||||||
context.call_cb(Event::LocationChanged(Some(from_id)));
|
context.emit_event(Event::LocationChanged(Some(from_id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,7 +1120,7 @@ async fn create_or_lookup_group(
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1179,7 +1179,7 @@ async fn create_or_lookup_group(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if send_EVENT_CHAT_MODIFIED {
|
if send_EVENT_CHAT_MODIFIED {
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
}
|
}
|
||||||
Ok((chat_id, chat_id_blocked))
|
Ok((chat_id, chat_id_blocked))
|
||||||
}
|
}
|
||||||
@@ -1300,7 +1300,7 @@ async fn create_or_lookup_adhoc_group(
|
|||||||
chat::add_to_chat_contacts_table(context, new_chat_id, member_id).await;
|
chat::add_to_chat_contacts_table(context, new_chat_id, member_id).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.call_cb(Event::ChatModified(new_chat_id));
|
context.emit_event(Event::ChatModified(new_chat_id));
|
||||||
|
|
||||||
Ok((new_chat_id, create_blocked))
|
Ok((new_chat_id, create_blocked))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ pub(crate) async fn dc_delete_file(context: &Context, path: impl AsRef<Path>) ->
|
|||||||
let dpath = format!("{}", path.as_ref().to_string_lossy());
|
let dpath = format!("{}", path.as_ref().to_string_lossy());
|
||||||
match fs::remove_file(path_abs).await {
|
match fs::remove_file(path_abs).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
context.call_cb(Event::DeletedBlobFile(dpath));
|
context.emit_event(Event::DeletedBlobFile(dpath));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|||||||
@@ -1,12 +1,66 @@
|
|||||||
//! # Events specification
|
//! # Events specification
|
||||||
|
|
||||||
use async_std::path::PathBuf;
|
use async_std::path::PathBuf;
|
||||||
|
use crossbeam_channel::{bounded as channel, Receiver, Sender, TrySendError};
|
||||||
|
|
||||||
use strum::EnumProperty;
|
use strum::EnumProperty;
|
||||||
|
|
||||||
use crate::chat::ChatId;
|
use crate::chat::ChatId;
|
||||||
use crate::message::MsgId;
|
use crate::message::MsgId;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Events {
|
||||||
|
receiver: Receiver<Event>,
|
||||||
|
sender: Sender<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Events {
|
||||||
|
fn default() -> Self {
|
||||||
|
let (sender, receiver) = channel(1_000);
|
||||||
|
|
||||||
|
Self { receiver, sender }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Events {
|
||||||
|
pub fn emit(&self, event: Event) {
|
||||||
|
match self.sender.try_send(event) {
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(TrySendError::Full(event)) => {
|
||||||
|
// when we are full, we pop remove the oldest event and push on the new one
|
||||||
|
let _ = self.receiver.try_recv();
|
||||||
|
|
||||||
|
// try again
|
||||||
|
self.emit(event);
|
||||||
|
}
|
||||||
|
Err(TrySendError::Disconnected(_)) => {
|
||||||
|
unreachable!("unable to emit event, channel disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the event emitter.
|
||||||
|
pub fn get_emitter(&self) -> EventEmitter {
|
||||||
|
EventEmitter(self.receiver.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EventEmitter(Receiver<Event>);
|
||||||
|
|
||||||
|
impl EventEmitter {
|
||||||
|
/// Blocking recv of an event. Return `None` if the `Sender` has been droped.
|
||||||
|
pub fn recv_sync(&self) -> Option<Event> {
|
||||||
|
self.0.recv().ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blocking async recv of an event. Return `None` if the `Sender` has been droped.
|
||||||
|
pub async fn recv(&self) -> Option<Event> {
|
||||||
|
// TODO: change once we can use async channels internally.
|
||||||
|
self.0.recv().ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
/// Returns the corresponding Event id.
|
/// Returns the corresponding Event id.
|
||||||
pub fn as_id(&self) -> i32 {
|
pub fn as_id(&self) -> i32 {
|
||||||
|
|||||||
14
src/imex.rs
14
src/imex.rs
@@ -377,7 +377,7 @@ async fn imex_inner(
|
|||||||
ensure!(param.is_some(), "No Import/export dir/file given.");
|
ensure!(param.is_some(), "No Import/export dir/file given.");
|
||||||
|
|
||||||
info!(context, "Import/export process started.");
|
info!(context, "Import/export process started.");
|
||||||
context.call_cb(Event::ImexProgress(10));
|
context.emit_event(Event::ImexProgress(10));
|
||||||
|
|
||||||
ensure!(context.sql.is_open().await, "Database not opened.");
|
ensure!(context.sql.is_open().await, "Database not opened.");
|
||||||
|
|
||||||
@@ -401,11 +401,11 @@ async fn imex_inner(
|
|||||||
match success {
|
match success {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
info!(context, "IMEX successfully completed");
|
info!(context, "IMEX successfully completed");
|
||||||
context.call_cb(Event::ImexProgress(1000));
|
context.emit_event(Event::ImexProgress(1000));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
context.call_cb(Event::ImexProgress(0));
|
context.emit_event(Event::ImexProgress(0));
|
||||||
bail!("IMEX FAILED to complete: {}", err);
|
bail!("IMEX FAILED to complete: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,7 +489,7 @@ async fn import_backup(context: &Context, backup_to_import: impl AsRef<Path>) ->
|
|||||||
if permille > 990 {
|
if permille > 990 {
|
||||||
permille = 990
|
permille = 990
|
||||||
}
|
}
|
||||||
context.call_cb(Event::ImexProgress(permille));
|
context.emit_event(Event::ImexProgress(permille));
|
||||||
if file_blob.is_empty() {
|
if file_blob.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -565,7 +565,7 @@ async fn export_backup(context: &Context, dir: impl AsRef<Path>) -> Result<()> {
|
|||||||
dest_sql
|
dest_sql
|
||||||
.set_raw_config_int(context, "backup_time", now as i32)
|
.set_raw_config_int(context, "backup_time", now as i32)
|
||||||
.await?;
|
.await?;
|
||||||
context.call_cb(Event::ImexFileWritten(dest_path_filename));
|
context.emit_event(Event::ImexFileWritten(dest_path_filename));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -604,7 +604,7 @@ async fn add_files_to_export(context: &Context, sql: &Sql) -> Result<()> {
|
|||||||
}
|
}
|
||||||
processed_files_cnt += 1;
|
processed_files_cnt += 1;
|
||||||
let permille = max(min(processed_files_cnt * 1000 / total_files_cnt, 990), 10);
|
let permille = max(min(processed_files_cnt * 1000 / total_files_cnt, 990), 10);
|
||||||
context.call_cb(Event::ImexProgress(permille));
|
context.emit_event(Event::ImexProgress(permille));
|
||||||
|
|
||||||
let name_f = entry.file_name();
|
let name_f = entry.file_name();
|
||||||
let name = name_f.to_string_lossy();
|
let name = name_f.to_string_lossy();
|
||||||
@@ -761,7 +761,7 @@ async fn export_key_to_asc_file(
|
|||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
error!(context, "Cannot write key to {}", file_name.display());
|
error!(context, "Cannot write key to {}", file_name.display());
|
||||||
} else {
|
} else {
|
||||||
context.call_cb(Event::ImexFileWritten(file_name));
|
context.emit_event(Event::ImexFileWritten(file_name));
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ async fn set_delivered(context: &Context, msg_id: MsgId) {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
context.call_cb(Event::MsgDelivered { chat_id, msg_id });
|
context.emit_event(Event::MsgDelivered { chat_id, msg_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for DC_JOB_SEND_MSG_TO_SMTP
|
// special case for DC_JOB_SEND_MSG_TO_SMTP
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ pub async fn send_locations_to_chat(context: &Context, chat_id: ChatId, seconds:
|
|||||||
.await;
|
.await;
|
||||||
chat::add_info_msg(context, chat_id, stock_str).await;
|
chat::add_info_msg(context, chat_id, stock_str).await;
|
||||||
}
|
}
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
if 0 != seconds {
|
if 0 != seconds {
|
||||||
schedule_maybe_send_locations(context, false).await;
|
schedule_maybe_send_locations(context, false).await;
|
||||||
job::add(
|
job::add(
|
||||||
@@ -302,7 +302,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if continue_streaming {
|
if continue_streaming {
|
||||||
context.call_cb(Event::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
context.emit_event(Event::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
||||||
};
|
};
|
||||||
schedule_maybe_send_locations(context, false).await;
|
schedule_maybe_send_locations(context, false).await;
|
||||||
}
|
}
|
||||||
@@ -382,7 +382,7 @@ pub async fn delete_all(context: &Context) -> Result<(), Error> {
|
|||||||
.sql
|
.sql
|
||||||
.execute("DELETE FROM locations;", paramsv![])
|
.execute("DELETE FROM locations;", paramsv![])
|
||||||
.await?;
|
.await?;
|
||||||
context.call_cb(Event::LocationChanged(None));
|
context.emit_event(Event::LocationChanged(None));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,7 +714,7 @@ pub(crate) async fn job_maybe_send_locations_ended(
|
|||||||
.stock_system_msg(StockMessage::MsgLocationDisabled, "", "", 0)
|
.stock_system_msg(StockMessage::MsgLocationDisabled, "", "", 0)
|
||||||
.await;
|
.await;
|
||||||
chat::add_info_msg(context, chat_id, stock_str).await;
|
chat::add_info_msg(context, chat_id, stock_str).await;
|
||||||
context.call_cb(Event::ChatModified(chat_id));
|
context.emit_event(Event::ChatModified(chat_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job::Status::Finished(Ok(()))
|
job::Status::Finished(Ok(()))
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ macro_rules! error {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! emit_event {
|
macro_rules! emit_event {
|
||||||
($ctx:expr, $event:expr) => {
|
($ctx:expr, $event:expr) => {
|
||||||
$ctx.call_cb($event);
|
$ctx.emit_event($event);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1030,7 +1030,7 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !msg_ids.is_empty() {
|
if !msg_ids.is_empty() {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1112,7 +1112,7 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if send_event {
|
if send_event {
|
||||||
context.call_cb(Event::MsgsChanged {
|
context.emit_event(Event::MsgsChanged {
|
||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
});
|
});
|
||||||
@@ -1270,7 +1270,7 @@ pub async fn set_msg_failed(context: &Context, msg_id: MsgId, error: Option<impl
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
context.call_cb(Event::MsgFailed {
|
context.emit_event(Event::MsgFailed {
|
||||||
chat_id: msg.chat_id,
|
chat_id: msg.chat_id,
|
||||||
msg_id,
|
msg_id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -852,7 +852,7 @@ impl MimeMessage {
|
|||||||
message::mdn_from_ext(context, from_id, original_message_id, sent_timestamp)
|
message::mdn_from_ext(context, from_id, original_message_id, sent_timestamp)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
context.call_cb(Event::MsgRead { chat_id, msg_id });
|
context.emit_event(Event::MsgRead { chat_id, msg_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ macro_rules! joiner_progress {
|
|||||||
$progress >= 0 && $progress <= 1000,
|
$progress >= 0 && $progress <= 1000,
|
||||||
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
||||||
);
|
);
|
||||||
$context.call_cb($crate::events::Event::SecurejoinJoinerProgress {
|
$context.emit_event($crate::events::Event::SecurejoinJoinerProgress {
|
||||||
contact_id: $contact_id,
|
contact_id: $contact_id,
|
||||||
progress: $progress,
|
progress: $progress,
|
||||||
});
|
});
|
||||||
@@ -45,7 +45,7 @@ macro_rules! inviter_progress {
|
|||||||
$progress >= 0 && $progress <= 1000,
|
$progress >= 0 && $progress <= 1000,
|
||||||
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
||||||
);
|
);
|
||||||
$context.call_cb($crate::events::Event::SecurejoinInviterProgress {
|
$context.emit_event($crate::events::Event::SecurejoinInviterProgress {
|
||||||
contact_id: $contact_id,
|
contact_id: $contact_id,
|
||||||
progress: $progress,
|
progress: $progress,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ impl Smtp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if lp.send_server.is_empty() || lp.send_port == 0 {
|
if lp.send_server.is_empty() || lp.send_port == 0 {
|
||||||
context.call_cb(Event::ErrorNetwork("SMTP bad parameters.".into()));
|
context.emit_event(Event::ErrorNetwork("SMTP bad parameters.".into()));
|
||||||
return Err(Error::BadParameters);
|
return Err(Error::BadParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ impl Smtp {
|
|||||||
self.transport = Some(trans);
|
self.transport = Some(trans);
|
||||||
self.last_success = Some(Instant::now());
|
self.last_success = Some(Instant::now());
|
||||||
|
|
||||||
context.call_cb(Event::SmtpConnected(format!(
|
context.emit_event(Event::SmtpConnected(format!(
|
||||||
"SMTP-LOGIN as {} ok",
|
"SMTP-LOGIN as {} ok",
|
||||||
lp.send_user,
|
lp.send_user,
|
||||||
)));
|
)));
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ impl Smtp {
|
|||||||
if let Some(ref mut transport) = self.transport {
|
if let Some(ref mut transport) = self.transport {
|
||||||
transport.send(mail).await.map_err(Error::SendError)?;
|
transport.send(mail).await.map_err(Error::SendError)?;
|
||||||
|
|
||||||
context.call_cb(Event::SmtpMessageSent(format!(
|
context.emit_event(Event::SmtpMessageSent(format!(
|
||||||
"Message len={} was smtp-sent to {}",
|
"Message len={} was smtp-sent to {}",
|
||||||
message_len, recipients_display
|
message_len, recipients_display
|
||||||
)));
|
)));
|
||||||
|
|||||||
Reference in New Issue
Block a user