Display chat time stamps in configured time zone
This commit is contained in:
parent
43a8b91dca
commit
1189e3eb7b
8 changed files with 30 additions and 10 deletions
|
|
@ -4,6 +4,7 @@ use crossterm::style::Stylize;
|
||||||
use euphoxide::api::{MessageId, Snowflake, Time};
|
use euphoxide::api::{MessageId, Snowflake, Time};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use toss::{Style, Styled};
|
use toss::{Style, Styled};
|
||||||
|
use tz::TimeZone;
|
||||||
|
|
||||||
use crate::store::Msg;
|
use crate::store::Msg;
|
||||||
use crate::ui::ChatMsg;
|
use crate::ui::ChatMsg;
|
||||||
|
|
@ -207,6 +208,7 @@ pub struct SmallMessage {
|
||||||
pub id: MessageId,
|
pub id: MessageId,
|
||||||
pub parent: Option<MessageId>,
|
pub parent: Option<MessageId>,
|
||||||
pub time: Time,
|
pub time: Time,
|
||||||
|
pub time_zone: &'static TimeZone,
|
||||||
pub nick: String,
|
pub nick: String,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub seen: bool,
|
pub seen: bool,
|
||||||
|
|
@ -270,8 +272,8 @@ impl Msg for SmallMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatMsg for SmallMessage {
|
impl ChatMsg for SmallMessage {
|
||||||
fn time(&self) -> OffsetDateTime {
|
fn time(&self) -> Option<OffsetDateTime> {
|
||||||
self.time.0
|
crate::util::convert_to_time_zone(self.time_zone, self.time.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn styled(&self) -> (Styled, Styled) {
|
fn styled(&self) -> (Styled, Styled) {
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ impl Msg for LogMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatMsg for LogMsg {
|
impl ChatMsg for LogMsg {
|
||||||
fn time(&self) -> OffsetDateTime {
|
fn time(&self) -> Option<OffsetDateTime> {
|
||||||
self.time
|
Some(self.time)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn styled(&self) -> (Styled, Styled) {
|
fn styled(&self) -> (Styled, Styled) {
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ fn update_config_with_args(config: &mut Config, args: &Args) {
|
||||||
|
|
||||||
fn open_vault(config: &Config, dirs: &ProjectDirs) -> anyhow::Result<Vault> {
|
fn open_vault(config: &Config, dirs: &ProjectDirs) -> anyhow::Result<Vault> {
|
||||||
let time_zone = util::load_time_zone(config.time_zone_ref())?;
|
let time_zone = util::load_time_zone(config.time_zone_ref())?;
|
||||||
|
let time_zone = Box::leak(Box::new(time_zone));
|
||||||
|
|
||||||
let vault = if config.ephemeral {
|
let vault = if config.ephemeral {
|
||||||
vault::launch_in_memory(time_zone)?
|
vault::launch_in_memory(time_zone)?
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use self::tree::TreeViewState;
|
||||||
use super::UiError;
|
use super::UiError;
|
||||||
|
|
||||||
pub trait ChatMsg {
|
pub trait ChatMsg {
|
||||||
fn time(&self) -> OffsetDateTime;
|
fn time(&self) -> Option<OffsetDateTime>;
|
||||||
fn styled(&self) -> (Styled, Styled);
|
fn styled(&self) -> (Styled, Styled);
|
||||||
fn edit(nick: &str, content: &str) -> (Styled, Styled);
|
fn edit(nick: &str, content: &str) -> (Styled, Styled);
|
||||||
fn pseudo(nick: &str, content: &str) -> (Styled, Styled);
|
fn pseudo(nick: &str, content: &str) -> (Styled, Styled);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ pub fn msg<M: Msg + ChatMsg>(
|
||||||
|
|
||||||
Join5::horizontal(
|
Join5::horizontal(
|
||||||
Seen::new(msg.seen()).segment().with_fixed(true),
|
Seen::new(msg.seen()).segment().with_fixed(true),
|
||||||
Time::new(Some(msg.time()), style_time(highlighted))
|
Time::new(msg.time(), style_time(highlighted))
|
||||||
.padding()
|
.padding()
|
||||||
.with_right(1)
|
.with_right(1)
|
||||||
.with_stretch(true)
|
.with_stretch(true)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use tz::{TimeZone, TzError};
|
use tz::{TimeZone, TzError};
|
||||||
|
|
||||||
pub trait InfallibleExt {
|
pub trait InfallibleExt {
|
||||||
|
|
@ -35,3 +36,14 @@ pub fn load_time_zone(tz_string: Option<&str>) -> Result<TimeZone, TzError> {
|
||||||
Some(tz_string) => TimeZone::from_posix_tz(tz_string),
|
Some(tz_string) => TimeZone::from_posix_tz(tz_string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_time_zone(tz: &TimeZone, time: OffsetDateTime) -> Option<OffsetDateTime> {
|
||||||
|
let utc_offset_in_seconds = tz
|
||||||
|
.find_local_time_type(time.unix_timestamp())
|
||||||
|
.ok()?
|
||||||
|
.ut_offset();
|
||||||
|
|
||||||
|
let utc_offset = UtcOffset::from_whole_seconds(utc_offset_in_seconds).ok()?;
|
||||||
|
|
||||||
|
Some(time.to_offset(utc_offset))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub use self::euph::{EuphRoomVault, EuphVault, RoomIdentifier};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Vault {
|
pub struct Vault {
|
||||||
tokio_vault: TokioVault,
|
tokio_vault: TokioVault,
|
||||||
time_zone: TimeZone,
|
time_zone: &'static TimeZone,
|
||||||
ephemeral: bool,
|
ephemeral: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl Vault {
|
||||||
|
|
||||||
fn launch_from_connection(
|
fn launch_from_connection(
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
time_zone: TimeZone,
|
time_zone: &'static TimeZone,
|
||||||
ephemeral: bool,
|
ephemeral: bool,
|
||||||
) -> rusqlite::Result<Vault> {
|
) -> rusqlite::Result<Vault> {
|
||||||
conn.pragma_update(None, "foreign_keys", true)?;
|
conn.pragma_update(None, "foreign_keys", true)?;
|
||||||
|
|
@ -64,7 +64,7 @@ fn launch_from_connection(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn launch(path: &Path, time_zone: TimeZone) -> rusqlite::Result<Vault> {
|
pub fn launch(path: &Path, time_zone: &'static TimeZone) -> rusqlite::Result<Vault> {
|
||||||
// If this fails, rusqlite will complain about not being able to open the db
|
// If this fails, rusqlite will complain about not being able to open the db
|
||||||
// file, which saves me from adding a separate vault error type.
|
// file, which saves me from adding a separate vault error type.
|
||||||
let _ = fs::create_dir_all(path.parent().expect("path to file"));
|
let _ = fs::create_dir_all(path.parent().expect("path to file"));
|
||||||
|
|
@ -82,7 +82,7 @@ pub fn launch(path: &Path, time_zone: TimeZone) -> rusqlite::Result<Vault> {
|
||||||
launch_from_connection(conn, time_zone, false)
|
launch_from_connection(conn, time_zone, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn launch_in_memory(time_zone: TimeZone) -> rusqlite::Result<Vault> {
|
pub fn launch_in_memory(time_zone: &'static TimeZone) -> rusqlite::Result<Vault> {
|
||||||
let conn = Connection::open_in_memory()?;
|
let conn = Connection::open_in_memory()?;
|
||||||
launch_from_connection(conn, time_zone, true)
|
launch_from_connection(conn, time_zone, true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,8 @@ macro_rules! euph_room_vault_actions {
|
||||||
$(
|
$(
|
||||||
struct $struct {
|
struct $struct {
|
||||||
room: RoomIdentifier,
|
room: RoomIdentifier,
|
||||||
|
#[allow(unused)]
|
||||||
|
time_zone: &'static tz::TimeZone,
|
||||||
$( $arg: $arg_ty, )*
|
$( $arg: $arg_ty, )*
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|
@ -248,6 +250,7 @@ macro_rules! euph_room_vault_actions {
|
||||||
pub async fn $fn(&self, $( $arg: $arg_ty, )* ) -> Result<$res, vault::tokio::Error<rusqlite::Error>> {
|
pub async fn $fn(&self, $( $arg: $arg_ty, )* ) -> Result<$res, vault::tokio::Error<rusqlite::Error>> {
|
||||||
self.vault.vault.tokio_vault.execute($struct {
|
self.vault.vault.tokio_vault.execute($struct {
|
||||||
room: self.room.clone(),
|
room: self.room.clone(),
|
||||||
|
time_zone: self.vault.vault.time_zone,
|
||||||
$( $arg, )*
|
$( $arg, )*
|
||||||
}).await
|
}).await
|
||||||
}
|
}
|
||||||
|
|
@ -607,6 +610,7 @@ impl Action for GetMsg {
|
||||||
id: MessageId(row.get::<_, WSnowflake>(0)?.0),
|
id: MessageId(row.get::<_, WSnowflake>(0)?.0),
|
||||||
parent: row.get::<_, Option<WSnowflake>>(1)?.map(|s| MessageId(s.0)),
|
parent: row.get::<_, Option<WSnowflake>>(1)?.map(|s| MessageId(s.0)),
|
||||||
time: row.get::<_, WTime>(2)?.0,
|
time: row.get::<_, WTime>(2)?.0,
|
||||||
|
time_zone: self.time_zone,
|
||||||
nick: row.get(3)?,
|
nick: row.get(3)?,
|
||||||
content: row.get(4)?,
|
content: row.get(4)?,
|
||||||
seen: row.get(5)?,
|
seen: row.get(5)?,
|
||||||
|
|
@ -700,6 +704,7 @@ impl Action for GetTree {
|
||||||
id: MessageId(row.get::<_, WSnowflake>(0)?.0),
|
id: MessageId(row.get::<_, WSnowflake>(0)?.0),
|
||||||
parent: row.get::<_, Option<WSnowflake>>(1)?.map(|s| MessageId(s.0)),
|
parent: row.get::<_, Option<WSnowflake>>(1)?.map(|s| MessageId(s.0)),
|
||||||
time: row.get::<_, WTime>(2)?.0,
|
time: row.get::<_, WTime>(2)?.0,
|
||||||
|
time_zone: self.time_zone,
|
||||||
nick: row.get(3)?,
|
nick: row.get(3)?,
|
||||||
content: row.get(4)?,
|
content: row.get(4)?,
|
||||||
seen: row.get(5)?,
|
seen: row.get(5)?,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue