Merge pull request #1250 from deltachat/flub-feat-mute-chat

Use SystemTime instead of i64
This commit is contained in:
Simon Laux
2020-02-09 15:46:19 +01:00
committed by GitHub
3 changed files with 50 additions and 40 deletions

View File

@@ -20,6 +20,7 @@ use std::fmt::Write;
use std::ptr; use std::ptr;
use std::str::FromStr; use std::str::FromStr;
use std::sync::RwLock; use std::sync::RwLock;
use std::time::{Duration, SystemTime};
use libc::uintptr_t; use libc::uintptr_t;
use num_traits::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive};
@@ -34,9 +35,6 @@ use deltachat::message::MsgId;
use deltachat::stock::StockMessage; use deltachat::stock::StockMessage;
use deltachat::*; use deltachat::*;
mod tools;
use crate::tools::time;
mod dc_array; mod dc_array;
mod string; mod string;
@@ -1421,14 +1419,18 @@ pub unsafe extern "C" fn dc_set_chat_mute_duration(
eprintln!("ignoring careless call to dc_set_chat_mute_duration()"); eprintln!("ignoring careless call to dc_set_chat_mute_duration()");
return 0; return 0;
} }
let ffi_context = &*context;
let muteDuration = match duration { let muteDuration = match duration {
0 => MuteDuration::NotMuted, 0 => MuteDuration::NotMuted,
-1 => MuteDuration::Forever, -1 => MuteDuration::Forever,
_ => MuteDuration::Until(time() + duration), n if n > 0 => MuteDuration::Until(SystemTime::now() + Duration::from_secs(duration as u64)),
_ => {
ffi_context.warning(
"dc_chat_set_mute_duration(): Can not use negative duration other than -1",
);
return 0;
}
}; };
let ffi_context = &*context;
ffi_context ffi_context
.with_inner(|ctx| { .with_inner(|ctx| {
chat::set_muted(ctx, ChatId::new(chat_id), muteDuration) chat::set_muted(ctx, ChatId::new(chat_id), muteDuration)
@@ -2532,10 +2534,14 @@ pub unsafe extern "C" fn dc_chat_get_remaining_mute_duration(chat: *mut dc_chat_
if !ffi_chat.chat.is_muted() { if !ffi_chat.chat.is_muted() {
return 0; return 0;
} }
// If the chat was muted to before the epoch, it is not muted.
match ffi_chat.chat.mute_duration { match ffi_chat.chat.mute_duration {
MuteDuration::NotMuted => 0, MuteDuration::NotMuted => 0,
MuteDuration::Forever => -1, MuteDuration::Forever => -1,
MuteDuration::Until(timestamp) => timestamp - time(), MuteDuration::Until(when) => when
.duration_since(SystemTime::UNIX_EPOCH)
.map(|d| d.as_secs() as i64)
.unwrap_or(0),
} }
} }

View File

@@ -1,8 +0,0 @@
use std::time::SystemTime;
pub(crate) fn time() -> i64 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs() as i64
}

View File

@@ -1,6 +1,8 @@
//! # Chat module //! # Chat module
use std::convert::TryFrom;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime};
use itertools::Itertools; use itertools::Itertools;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
@@ -691,7 +693,7 @@ impl Chat {
match self.mute_duration { match self.mute_duration {
MuteDuration::NotMuted => false, MuteDuration::NotMuted => false,
MuteDuration::Forever => true, MuteDuration::Forever => true,
MuteDuration::Until(timestamp) => timestamp > time(), MuteDuration::Until(when) => when > SystemTime::now(),
} }
} }
@@ -1921,17 +1923,23 @@ pub fn shall_attach_selfavatar(context: &Context, chat_id: ChatId) -> Result<boo
pub enum MuteDuration { pub enum MuteDuration {
NotMuted, NotMuted,
Forever, Forever,
Until(i64), Until(SystemTime),
} }
impl rusqlite::types::ToSql for MuteDuration { impl rusqlite::types::ToSql for MuteDuration {
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> { fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
let duration = match &self { let duration: i64 = match &self {
MuteDuration::NotMuted => 0, MuteDuration::NotMuted => 0,
MuteDuration::Forever => -1, MuteDuration::Forever => -1,
MuteDuration::Until(timestamp) => *timestamp as i64, MuteDuration::Until(when) => {
let duration = when
.duration_since(SystemTime::UNIX_EPOCH)
.map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?;
i64::try_from(duration.as_secs())
.map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?
}
}; };
let val = rusqlite::types::Value::Integer(duration as i64); let val = rusqlite::types::Value::Integer(duration);
let out = rusqlite::types::ToSqlOutput::Owned(val); let out = rusqlite::types::ToSqlOutput::Owned(val);
Ok(out) Ok(out)
} }
@@ -1939,24 +1947,19 @@ impl rusqlite::types::ToSql for MuteDuration {
impl rusqlite::types::FromSql for MuteDuration { impl rusqlite::types::FromSql for MuteDuration {
fn column_result(value: rusqlite::types::ValueRef) -> rusqlite::types::FromSqlResult<Self> { fn column_result(value: rusqlite::types::ValueRef) -> rusqlite::types::FromSqlResult<Self> {
// Would be nice if we could use match here, but alas. // Negative values other than -1 should not be in the
i64::column_result(value).and_then(|val| { // database. If found they'll be NotMuted.
Ok({ match i64::column_result(value)? {
match val { 0 => Ok(MuteDuration::NotMuted),
0 => MuteDuration::NotMuted, -1 => Ok(MuteDuration::Forever),
-1 => MuteDuration::Forever, n if n > 0 => match SystemTime::UNIX_EPOCH.checked_add(Duration::from_secs(n as u64)) {
_ => { Some(t) => Ok(MuteDuration::Until(t)),
if val <= time() { None => Err(rusqlite::types::FromSqlError::OutOfRange(n)),
MuteDuration::NotMuted },
} else { _ => Ok(MuteDuration::NotMuted),
MuteDuration::Until(val)
} }
} }
} }
})
})
}
}
pub fn set_muted(context: &Context, chat_id: ChatId, duration: MuteDuration) -> Result<(), Error> { pub fn set_muted(context: &Context, chat_id: ChatId, duration: MuteDuration) -> Result<(), Error> {
ensure!(!chat_id.is_special(), "Invalid chat ID"); ensure!(!chat_id.is_special(), "Invalid chat ID");
@@ -1973,7 +1976,6 @@ pub fn set_muted(context: &Context, chat_id: ChatId, duration: MuteDuration) ->
} else { } else {
bail!("Failed to set name"); bail!("Failed to set name");
} }
Ok(()) Ok(())
} }
@@ -2877,13 +2879,23 @@ mod tests {
false false
); );
// Timed in the future // Timed in the future
set_muted(&t.ctx, chat_id, MuteDuration::Until(time() + 3600)).unwrap(); set_muted(
&t.ctx,
chat_id,
MuteDuration::Until(SystemTime::now() + Duration::from_secs(3600)),
)
.unwrap();
assert_eq!( assert_eq!(
Chat::load_from_db(&t.ctx, chat_id).unwrap().is_muted(), Chat::load_from_db(&t.ctx, chat_id).unwrap().is_muted(),
true true
); );
// Time in the past // Time in the past
set_muted(&t.ctx, chat_id, MuteDuration::Until(time() - 3600)).unwrap(); set_muted(
&t.ctx,
chat_id,
MuteDuration::Until(SystemTime::now() - Duration::from_secs(3600)),
)
.unwrap();
assert_eq!( assert_eq!(
Chat::load_from_db(&t.ctx, chat_id).unwrap().is_muted(), Chat::load_from_db(&t.ctx, chat_id).unwrap().is_muted(),
false false