Browse Source

ui: add manual_refresh, refresh_command settings

manual_refresh Ar boolean
  (optional) if true, do not monitor account for changes (shortcut listing.refresh)
  refresh_command Ar String
  (optional) command to execute when manually refreshing (shortcut listing.refresh)
async
Manos Pitsidianakis 2 years ago
parent
commit
86d8419ce7
Signed by: epilys GPG Key ID: 73627C2F690DF710
  1. 31
      meli.conf.5
  2. 4
      ui/src/components/mail/listing/compact.rs
  3. 23
      ui/src/components/mail/listing/conversations.rs
  4. 10
      ui/src/conf.rs
  5. 12
      ui/src/conf/accounts.rs
  6. 41
      ui/src/conf/listing.rs

31
meli.conf.5

@ -53,7 +53,7 @@ is not a comment:
The accepted regular expression is
.Li ^\es*include\es*\&\\&\e"(\e\e.|[^\e"])+\e"\es*$
.Sh SECTIONS
The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
The top level sections of the config are accounts, shortcuts, notifications, pager, listing, composing, pgp, terminal.
.Pp
.Sy example configuration
@ -138,6 +138,12 @@ plain:shows one row per mail, regardless of threading
.It Ic read_only Ar boolean
attempt to not make any changes to this account.
.Pq Em false
.It Ic manual_refresh Ar boolean
(optional) if true, do not monitor account for changes (shortcut listing.refresh)
.Pq Em false
.It Ic refresh_command Ar String
(optional) command to execute when manually refreshing (shortcut listing.refresh)
.Pq Em None
.It Ic cache_type Ar String
(optional) choose which cache backend to use. Available options are 'none' and 'sqlite3'
.Pq Em "sqlite3"
@ -351,6 +357,14 @@ Go to next account.
Start new mail draft in new tab
.\" default value
.Pq Em m
.It Ic set_seen
Set thread as seen.
.\" default value
.Pq Em n
.It Ic refresh
Manually request a folder refresh.
.\" default value
.Pq Em F5
.It Ic search
Search within list of e-mails.
.\" default value
@ -563,6 +577,21 @@ enable freedesktop-spec notifications. this is usually what you want
.\" default value
.Pq Em 80
.El
.Sh LISTING
.Bl -tag -width 36n
.It Ic context_lines Ar num
(optional) number of context lines when going to next page. (Unimplemented)
.\" default value
.Pq Em 0
.It Ic datetime_fmt Ar String
(optional) datetime formatting passed verbatim to strftime(3).
.\" default value
.Pq Em \&%Y-\&%m-\&%d \&%T
.It Ic recent_dates Ar Boolean
(optional) Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
.\" default value
.Pq Em true
.El
.Sh TAGS
.Bl -tag -width 36n
.It Ic colours Ar hash table String[Color]

4
ui/src/components/mail/listing/compact.rs

@ -591,7 +591,7 @@ impl CompactListing {
subject.truncate_at_boundary(150);
if thread_node.len() > 0 {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!(
"{}{}",
@ -603,7 +603,7 @@ impl CompactListing {
}
} else {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(subject),
flag: FlagString(format!(
"{}{}",

23
ui/src/components/mail/listing/conversations.rs

@ -562,7 +562,7 @@ impl ConversationsListing {
subject.truncate_at_boundary(150);
if thread_node.len() > 0 {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!(
"{}{}",
@ -574,7 +574,7 @@ impl ConversationsListing {
}
} else {
EntryStrings {
date: DateString(ConversationsListing::format_date(thread_node)),
date: DateString(ConversationsListing::format_date(context, thread_node)),
subject: SubjectString(subject),
flag: FlagString(format!(
"{}{}",
@ -890,28 +890,37 @@ impl ConversationsListing {
}
}
pub(super) fn format_date(thread_node: &ThreadNode) -> String {
pub(super) fn format_date(context: &Context, thread_node: &ThreadNode) -> String {
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(thread_node.date());
let now: std::time::Duration = std::time::SystemTime::now()
.duration_since(d)
.unwrap_or_else(|_| std::time::Duration::new(std::u64::MAX, 0));
match now.as_secs() {
n if n < 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 60 * 60 => format!(
"{} minute{} ago",
n / (60),
if n / 60 == 1 { "" } else { "s" }
),
n if n < 24 * 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 24 * 60 * 60 => format!(
"{} hour{} ago",
n / (60 * 60),
if n / (60 * 60) == 1 { "" } else { "s" }
),
n if n < 7 * 24 * 60 * 60 => format!(
n if context.settings.listing.recent_dates && n < 7 * 24 * 60 * 60 => format!(
"{} day{} ago",
n / (24 * 60 * 60),
if n / (24 * 60 * 60) == 1 { "" } else { "s" }
),
_ => melib::datetime::timestamp_to_string(thread_node.date(), Some("%Y-%m-%d %T")),
_ => melib::datetime::timestamp_to_string(
thread_node.date(),
context
.settings
.listing
.datetime_fmt
.as_ref()
.map(String::as_str)
.or(Some("%Y-%m-%d %T")),
),
}
}

10
ui/src/conf.rs

@ -31,6 +31,7 @@ pub mod pgp;
pub mod tags;
#[macro_use]
pub mod shortcuts;
mod listing;
pub mod terminal;
pub mod accounts;
@ -41,6 +42,7 @@ pub use self::shortcuts::*;
pub use self::tags::*;
use self::default_vals::*;
use self::listing::ListingSettings;
use self::notifications::NotificationsSettings;
use self::terminal::TerminalSettings;
use crate::pager::PagerSettings;
@ -68,6 +70,7 @@ macro_rules! split_command {
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct MailUIConf {
pub pager: Option<PagerSettings>,
pub listing: Option<ListingSettings>,
pub notifications: Option<NotificationsSettings>,
pub shortcuts: Option<Shortcuts>,
pub composing: Option<ComposingSettings>,
@ -114,6 +117,8 @@ pub struct FileAccount {
cache_type: CacheType,
#[serde(default)]
pub manual_refresh: bool,
#[serde(default = "none")]
pub refresh_command: Option<String>,
#[serde(flatten)]
#[serde(deserialize_with = "extra_settings")]
pub extra: HashMap<String, String>, /* use custom deserializer to convert any given value (eg bool, number, etc) to string */
@ -230,6 +235,8 @@ pub struct FileSettings {
#[serde(default)]
pager: PagerSettings,
#[serde(default)]
listing: ListingSettings,
#[serde(default)]
notifications: NotificationsSettings,
#[serde(default)]
shortcuts: Shortcuts,
@ -267,6 +274,7 @@ impl AccountConf {
pub struct Settings {
pub accounts: HashMap<String, AccountConf>,
pub pager: PagerSettings,
pub listing: ListingSettings,
pub notifications: NotificationsSettings,
pub shortcuts: Shortcuts,
pub tags: TagsSettings,
@ -359,6 +367,7 @@ impl FileSettings {
folders,
extra,
manual_refresh,
refresh_command: _,
index_style: _,
cache_type: _,
} = acc;
@ -401,6 +410,7 @@ impl Settings {
Ok(Settings {
accounts: s,
pager: fs.pager,
listing: fs.listing,
notifications: fs.notifications,
shortcuts: fs.shortcuts,
tags: fs.tags,

12
ui/src/conf/accounts.rs

@ -723,6 +723,18 @@ impl Account {
None
}
pub fn refresh(&mut self, folder_hash: FolderHash) -> Result<()> {
if let Some(ref refresh_command) = self.settings.conf().refresh_command {
let parts = crate::split_command!(refresh_command);
let (cmd, args) = (parts[0], &parts[1..]);
std::process::Command::new(cmd)
.args(args)
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.spawn()?;
return Ok(());
}
let sender_ = self.sender.clone();
let r = RefreshEventConsumer::new(Box::new(move |r| {
sender_.send(ThreadEvent::from(r)).unwrap();

41
ui/src/conf/listing.rs

@ -0,0 +1,41 @@
/*
* meli - listing conf module
*
* Copyright 2020 Manos Pitsidianakis
*
* This file is part of meli.
*
* meli is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* meli is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use super::default_vals::*;
/// Settings for mail listings
#[derive(Debug, Deserialize, Clone, Default, Serialize)]
pub struct ListingSettings {
/// Number of context lines when going to next page.
/// Default: 0
#[serde(default = "zero_val")]
pub context_lines: usize,
/// Datetime formatting passed verbatim to strftime(3).
/// Default: %Y-%m-%d %T
#[serde(default = "none")]
pub datetime_fmt: Option<String>,
/// Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
/// Default: true
#[serde(default = "true_val")]
pub recent_dates: bool,
}
Loading…
Cancel
Save