ui: load vcards to addressbook with vcard_folder account setting
parent
689327651f
commit
afff63c781
|
@ -124,8 +124,10 @@ plain:shows one row per mail, regardless of threading
|
|||
attempt to not make any changes to this account.
|
||||
.Pq Em false
|
||||
.It Ic cache_type Ar String
|
||||
choose which cache backend to use. Available options are 'none' and 'sqlite3'
|
||||
(optional) choose which cache backend to use. Available options are 'none' and 'sqlite3'
|
||||
.Pq Em "sqlite3"
|
||||
.It Ic vcard_folder Ar String
|
||||
(optional) Folder that contains .vcf files. They are parsed and imported read-only.
|
||||
.It Ic folders Ar folder_config
|
||||
(optional) configuration for each folder. Its format is described below in
|
||||
.Sx FOLDERS Ns
|
||||
|
|
|
@ -61,7 +61,7 @@ pub struct AddressBook {
|
|||
display_name: String,
|
||||
created: DateTime<Local>,
|
||||
last_edited: DateTime<Local>,
|
||||
cards: FnvHashMap<CardId, Card>,
|
||||
pub cards: FnvHashMap<CardId, Card>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
|
@ -95,6 +95,24 @@ impl AddressBook {
|
|||
cards: FnvHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_account(s: &crate::conf::AccountSettings) -> AddressBook {
|
||||
let mut ret = AddressBook::new(s.name.clone());
|
||||
|
||||
#[cfg(feature = "vcard")]
|
||||
{
|
||||
if let Some(vcard_path) = s.vcard_folder() {
|
||||
if let Ok(cards) = vcard::load_cards(&std::path::Path::new(vcard_path)) {
|
||||
for c in cards {
|
||||
ret.add_card(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn add_card(&mut self, card: Card) {
|
||||
self.cards.insert(card.id, card);
|
||||
}
|
||||
|
@ -108,7 +126,7 @@ impl AddressBook {
|
|||
self.cards
|
||||
.values()
|
||||
.filter(|c| c.email.contains(term))
|
||||
.map(|c| c.email.clone())
|
||||
.map(|c| format!("{} <{}>", &c.name, &c.email))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,11 @@ impl AccountSettings {
|
|||
pub fn subscribed_folders(&self) -> &Vec<String> {
|
||||
&self.subscribed_folders
|
||||
}
|
||||
|
||||
#[cfg(feature = "vcard")]
|
||||
pub fn vcard_folder(&self) -> Option<&str> {
|
||||
self.extra.get("vcard_folder").map(String::as_str)
|
||||
}
|
||||
}
|
||||
|
||||
#[serde(default)]
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
* meli
|
||||
*
|
||||
* Copyright 2019 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::*;
|
||||
|
||||
use melib::CardId;
|
||||
|
@ -88,8 +108,8 @@ impl ContactList {
|
|||
}
|
||||
|
||||
fn initialize(&mut self, context: &mut Context) {
|
||||
let account = &mut context.accounts[self.account_pos];
|
||||
let book = &mut account.address_book;
|
||||
let account = &context.accounts[self.account_pos];
|
||||
let book = &account.address_book;
|
||||
self.length = book.len();
|
||||
|
||||
self.id_positions.clear();
|
||||
|
@ -97,69 +117,39 @@ impl ContactList {
|
|||
self.id_positions.reserve(book.len());
|
||||
}
|
||||
self.dirty = true;
|
||||
let mut min_width = ("Name".len(), "E-mail".len(), 0, 0, 0);
|
||||
let mut min_width = ("Name".len(), "E-mail".len(), 0, "external".len(), 0, 0);
|
||||
|
||||
for c in book.values() {
|
||||
self.id_positions.push(*c.id());
|
||||
min_width.0 = cmp::max(min_width.0, c.name().split_graphemes().len()); /* name */
|
||||
min_width.1 = cmp::max(min_width.1, c.email().split_graphemes().len()); /* email */
|
||||
min_width.2 = cmp::max(min_width.2, c.url().split_graphemes().len());
|
||||
/* name */
|
||||
min_width.0 = cmp::max(min_width.0, c.name().split_graphemes().len());
|
||||
/* email */
|
||||
min_width.1 = cmp::max(min_width.1, c.email().split_graphemes().len());
|
||||
/* url */
|
||||
min_width.2 = cmp::max(min_width.2, c.url().split_graphemes().len());
|
||||
}
|
||||
|
||||
/* name column */
|
||||
self.data_columns.columns[0] = CellBuffer::new_with_context(
|
||||
min_width.0,
|
||||
self.length + 1,
|
||||
Cell::with_char(' '),
|
||||
context,
|
||||
);
|
||||
self.data_columns.columns[0] =
|
||||
CellBuffer::new_with_context(min_width.0, self.length, Cell::with_char(' '), context);
|
||||
/* email column */
|
||||
self.data_columns.columns[1] = CellBuffer::new_with_context(
|
||||
min_width.1,
|
||||
self.length + 1,
|
||||
Cell::with_char(' '),
|
||||
context,
|
||||
);
|
||||
self.data_columns.columns[1] =
|
||||
CellBuffer::new_with_context(min_width.1, self.length, Cell::with_char(' '), context);
|
||||
/* url column */
|
||||
self.data_columns.columns[2] = CellBuffer::new_with_context(
|
||||
min_width.2,
|
||||
self.length + 1,
|
||||
self.data_columns.columns[2] =
|
||||
CellBuffer::new_with_context(min_width.2, self.length, Cell::with_char(' '), context);
|
||||
/* source column */
|
||||
self.data_columns.columns[3] = CellBuffer::new_with_context(
|
||||
"external".len(),
|
||||
self.length,
|
||||
Cell::with_char(' '),
|
||||
context,
|
||||
);
|
||||
write_string_to_grid(
|
||||
"NAME",
|
||||
&mut self.data_columns.columns[0],
|
||||
Color::Black,
|
||||
Color::White,
|
||||
Attr::Bold,
|
||||
((0, 0), (MAX_COLS - 1, self.length)),
|
||||
None,
|
||||
);
|
||||
write_string_to_grid(
|
||||
"E-MAIL",
|
||||
&mut self.data_columns.columns[1],
|
||||
Color::Black,
|
||||
Color::White,
|
||||
Attr::Bold,
|
||||
((0, 0), (MAX_COLS - 1, self.length)),
|
||||
None,
|
||||
);
|
||||
|
||||
write_string_to_grid(
|
||||
"URL",
|
||||
&mut self.data_columns.columns[2],
|
||||
Color::Black,
|
||||
Color::White,
|
||||
Attr::Bold,
|
||||
((0, 0), (MAX_COLS - 1, self.length)),
|
||||
None,
|
||||
);
|
||||
|
||||
let account = &mut context.accounts[self.account_pos];
|
||||
let book = &mut account.address_book;
|
||||
for (idx, c) in book.values().enumerate() {
|
||||
let account = &context.accounts[self.account_pos];
|
||||
let book = &account.address_book;
|
||||
let mut book_values = book.values().collect::<Vec<&Card>>();
|
||||
book_values.sort_unstable_by_key(|c| c.name());
|
||||
for (idx, c) in book_values.iter().enumerate() {
|
||||
self.id_positions.push(*c.id());
|
||||
|
||||
write_string_to_grid(
|
||||
|
@ -168,7 +158,7 @@ impl ContactList {
|
|||
Color::Default,
|
||||
Color::Default,
|
||||
Attr::Default,
|
||||
((0, idx + 1), (min_width.0, idx + 1)),
|
||||
((0, idx), (min_width.0, idx)),
|
||||
None,
|
||||
);
|
||||
|
||||
|
@ -178,7 +168,7 @@ impl ContactList {
|
|||
Color::Default,
|
||||
Color::Default,
|
||||
Attr::Default,
|
||||
((0, idx + 1), (min_width.1, idx + 1)),
|
||||
((0, idx), (min_width.1, idx)),
|
||||
None,
|
||||
);
|
||||
|
||||
|
@ -188,7 +178,21 @@ impl ContactList {
|
|||
Color::Default,
|
||||
Color::Default,
|
||||
Attr::Default,
|
||||
((0, idx + 1), (min_width.2, idx + 1)),
|
||||
((0, idx), (min_width.2, idx)),
|
||||
None,
|
||||
);
|
||||
|
||||
write_string_to_grid(
|
||||
if c.external_resource() {
|
||||
"external"
|
||||
} else {
|
||||
"local"
|
||||
},
|
||||
&mut self.data_columns.columns[3],
|
||||
Color::Default,
|
||||
Color::Default,
|
||||
Attr::Default,
|
||||
((0, idx), (min_width.3, idx)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
@ -197,7 +201,7 @@ impl ContactList {
|
|||
let message = "Address book is empty.".to_string();
|
||||
self.data_columns.columns[0] = CellBuffer::new_with_context(
|
||||
message.len(),
|
||||
self.length + 1,
|
||||
self.length,
|
||||
Cell::with_char(' '),
|
||||
context,
|
||||
);
|
||||
|
@ -273,6 +277,7 @@ impl ContactList {
|
|||
|
||||
if a.name.grapheme_len() + s.len() > width + 1 {
|
||||
/* Print account name */
|
||||
let (x, y) =
|
||||
write_string_to_grid(&a.name, grid, fg_color, bg_color, Attr::Bold, area, None);
|
||||
write_string_to_grid(
|
||||
&s,
|
||||
|
@ -304,9 +309,15 @@ impl ContactList {
|
|||
),
|
||||
None,
|
||||
);
|
||||
|
||||
for x in x..=get_x(bottom_right!(area)) {
|
||||
grid[(x, y)].set_fg(fg_color);
|
||||
grid[(x, y)].set_bg(bg_color);
|
||||
}
|
||||
} else {
|
||||
/* Print account name */
|
||||
|
||||
let (x, y) =
|
||||
write_string_to_grid(&a.name, grid, fg_color, bg_color, Attr::Bold, area, None);
|
||||
write_string_to_grid(
|
||||
&s,
|
||||
|
@ -323,11 +334,16 @@ impl ContactList {
|
|||
),
|
||||
None,
|
||||
);
|
||||
for x in x..=get_x(bottom_right!(area)) {
|
||||
grid[(x, y)].set_fg(fg_color);
|
||||
grid[(x, y)].set_bg(bg_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
||||
let upper_left = upper_left!(area);
|
||||
/* reserve top row for column headers */
|
||||
let upper_left = pos_inc(upper_left!(area), (0, 1));
|
||||
let bottom_right = bottom_right!(area);
|
||||
|
||||
if self.length == 0 {
|
||||
|
@ -341,7 +357,7 @@ impl ContactList {
|
|||
context.dirty_areas.push_back(area);
|
||||
return;
|
||||
}
|
||||
let rows = get_y(bottom_right) - get_y(upper_left);
|
||||
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
|
||||
|
||||
if let Some(mvm) = self.movement.take() {
|
||||
match mvm {
|
||||
|
@ -352,14 +368,14 @@ impl ContactList {
|
|||
self.new_cursor_pos = self.new_cursor_pos.saturating_sub(rows * multiplier);
|
||||
}
|
||||
PageMovement::Down(amount) => {
|
||||
if self.new_cursor_pos + amount + 1 < self.length {
|
||||
if self.new_cursor_pos + amount < self.length {
|
||||
self.new_cursor_pos += amount;
|
||||
} else {
|
||||
self.new_cursor_pos = self.length - 1;
|
||||
}
|
||||
}
|
||||
PageMovement::PageDown(multiplier) => {
|
||||
if self.new_cursor_pos + rows * multiplier + 1 < self.length {
|
||||
if self.new_cursor_pos + rows * multiplier < self.length {
|
||||
self.new_cursor_pos += rows * multiplier;
|
||||
} else if self.new_cursor_pos + rows * multiplier > self.length {
|
||||
self.new_cursor_pos = self.length - 1;
|
||||
|
@ -372,11 +388,7 @@ impl ContactList {
|
|||
self.new_cursor_pos = 0;
|
||||
}
|
||||
PageMovement::End => {
|
||||
if self.new_cursor_pos + rows > self.length {
|
||||
self.new_cursor_pos = self.length - 1;
|
||||
} else {
|
||||
self.new_cursor_pos = (self.length / rows) * rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -396,8 +408,8 @@ impl ContactList {
|
|||
continue; //bounds check
|
||||
}
|
||||
let new_area = (
|
||||
set_y(upper_left, get_y(upper_left) + (*idx % rows) + 1),
|
||||
set_y(bottom_right, get_y(upper_left) + (*idx % rows) + 1),
|
||||
set_y(upper_left, get_y(upper_left) + (*idx % rows)),
|
||||
set_y(bottom_right, get_y(upper_left) + (*idx % rows)),
|
||||
);
|
||||
self.highlight_line(grid, new_area, *idx);
|
||||
context.dirty_areas.push_back(new_area);
|
||||
|
@ -416,6 +428,7 @@ impl ContactList {
|
|||
self.data_columns.widths[0] = self.data_columns.columns[0].size().0; /* name */
|
||||
self.data_columns.widths[1] = self.data_columns.columns[1].size().0; /* email*/
|
||||
self.data_columns.widths[2] = self.data_columns.columns[2].size().0; /* url */
|
||||
self.data_columns.widths[3] = self.data_columns.columns[3].size().0; /* source */
|
||||
|
||||
let min_col_width = std::cmp::min(
|
||||
15,
|
||||
|
@ -431,10 +444,31 @@ impl ContactList {
|
|||
/* Page_no has changed, so draw new page */
|
||||
let mut x = get_x(upper_left);
|
||||
for i in 0..self.data_columns.columns.len() {
|
||||
let (column_width, column_height) = self.data_columns.columns[i].size();
|
||||
if self.data_columns.widths[i] == 0 {
|
||||
continue;
|
||||
}
|
||||
let (column_width, column_height) = self.data_columns.columns[i].size();
|
||||
write_string_to_grid(
|
||||
match i {
|
||||
0 => "NAME",
|
||||
1 => "E-MAIL",
|
||||
2 => "URL",
|
||||
3 => "SOURCE",
|
||||
_ => "",
|
||||
},
|
||||
grid,
|
||||
Color::Black,
|
||||
Color::White,
|
||||
Attr::Bold,
|
||||
(
|
||||
set_x(upper_left!(area), x),
|
||||
(
|
||||
std::cmp::min(get_x(bottom_right), x + (self.data_columns.widths[i])),
|
||||
get_y(upper_left!(area)),
|
||||
),
|
||||
),
|
||||
None,
|
||||
);
|
||||
copy_area(
|
||||
grid,
|
||||
&self.data_columns.columns[i],
|
||||
|
@ -461,12 +495,15 @@ impl ContactList {
|
|||
|
||||
change_colors(
|
||||
grid,
|
||||
(upper_left, set_y(bottom_right, get_y(upper_left))),
|
||||
(
|
||||
upper_left!(area),
|
||||
set_y(bottom_right, get_y(upper_left!(area))),
|
||||
),
|
||||
Color::Black,
|
||||
Color::White,
|
||||
);
|
||||
|
||||
if top_idx + rows + 1 > self.length {
|
||||
if top_idx + rows > self.length {
|
||||
clear_area(
|
||||
grid,
|
||||
(
|
||||
|
@ -478,11 +515,8 @@ impl ContactList {
|
|||
self.highlight_line(
|
||||
grid,
|
||||
(
|
||||
set_y(upper_left, get_y(upper_left) + (self.cursor_pos % rows) + 1),
|
||||
set_y(
|
||||
bottom_right,
|
||||
get_y(upper_left) + (self.cursor_pos % rows) + 1,
|
||||
),
|
||||
set_y(upper_left, get_y(upper_left) + (self.cursor_pos % rows)),
|
||||
set_y(bottom_right, get_y(upper_left) + (self.cursor_pos % rows)),
|
||||
),
|
||||
self.cursor_pos,
|
||||
);
|
||||
|
@ -550,10 +584,9 @@ impl Component for ContactList {
|
|||
}
|
||||
}
|
||||
let shortcuts = &self.get_shortcuts(context)[Self::DESCRIPTION];
|
||||
if self.view.is_none() {
|
||||
match *event {
|
||||
UIEvent::Input(ref key)
|
||||
if key == shortcuts["create_contact"] && self.view.is_none() =>
|
||||
{
|
||||
UIEvent::Input(ref key) if key == shortcuts["create_contact"] => {
|
||||
let mut manager = ContactManager::default();
|
||||
manager.set_parent_id(self.id);
|
||||
manager.account_pos = self.account_pos;
|
||||
|
@ -564,9 +597,7 @@ impl Component for ContactList {
|
|||
return true;
|
||||
}
|
||||
|
||||
UIEvent::Input(ref key)
|
||||
if key == shortcuts["edit_contact"] && self.length > 0 && self.view.is_none() =>
|
||||
{
|
||||
UIEvent::Input(ref key) if key == shortcuts["edit_contact"] && self.length > 0 => {
|
||||
let account = &mut context.accounts[self.account_pos];
|
||||
let book = &mut account.address_book;
|
||||
let card = book[&self.id_positions[self.cursor_pos]].clone();
|
||||
|
@ -580,7 +611,21 @@ impl Component for ContactList {
|
|||
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref key) if key == shortcuts["next_account"] && self.view.is_none() => {
|
||||
UIEvent::Input(ref key) if key == shortcuts["mail_contact"] && self.length > 0 => {
|
||||
let account = &context.accounts[self.account_pos];
|
||||
let book = &account.address_book;
|
||||
let card = &book[&self.id_positions[self.cursor_pos]];
|
||||
let mut draft: Draft = Draft::default();
|
||||
*draft.headers_mut().get_mut("To").unwrap() =
|
||||
format!("{} <{}>", &card.name(), &card.email());
|
||||
context.replies.push_back(UIEvent::Action(Tab(NewDraft(
|
||||
self.account_pos,
|
||||
Some(draft),
|
||||
))));
|
||||
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref key) if key == shortcuts["next_account"] => {
|
||||
let amount = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||
|
@ -603,6 +648,9 @@ impl Component for ContactList {
|
|||
self.account_pos += amount;
|
||||
self.set_dirty();
|
||||
self.initialized = false;
|
||||
self.cursor_pos = 0;
|
||||
self.new_cursor_pos = 0;
|
||||
self.length = 0;
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(
|
||||
|
@ -612,7 +660,7 @@ impl Component for ContactList {
|
|||
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref key) if key == shortcuts["prev_account"] && self.view.is_none() => {
|
||||
UIEvent::Input(ref key) if key == shortcuts["prev_account"] => {
|
||||
let amount = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||
|
@ -634,6 +682,9 @@ impl Component for ContactList {
|
|||
if self.account_pos >= amount {
|
||||
self.account_pos -= amount;
|
||||
self.set_dirty();
|
||||
self.cursor_pos = 0;
|
||||
self.new_cursor_pos = 0;
|
||||
self.length = 0;
|
||||
self.initialized = false;
|
||||
context
|
||||
.replies
|
||||
|
@ -643,9 +694,7 @@ impl Component for ContactList {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref k)
|
||||
if k == shortcuts["toggle_menu_visibility"] && self.view.is_none() =>
|
||||
{
|
||||
UIEvent::Input(ref k) if k == shortcuts["toggle_menu_visibility"] => {
|
||||
self.menu_visibility = !self.menu_visibility;
|
||||
self.set_dirty();
|
||||
}
|
||||
|
@ -665,7 +714,7 @@ impl Component for ContactList {
|
|||
)));
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(Key::Up) if self.view.is_none() => {
|
||||
UIEvent::Input(Key::Up) => {
|
||||
let amount = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||
|
@ -685,9 +734,7 @@ impl Component for ContactList {
|
|||
self.set_dirty();
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(Key::Down)
|
||||
if self.cursor_pos < self.length.saturating_sub(1) && self.view.is_none() =>
|
||||
{
|
||||
UIEvent::Input(Key::Down) if self.cursor_pos < self.length.saturating_sub(1) => {
|
||||
let amount = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||
|
@ -707,6 +754,60 @@ impl Component for ContactList {
|
|||
self.movement = Some(PageMovement::Down(amount));
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(Key::PageUp) => {
|
||||
let mult = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
||||
self.cmd_buf.clear();
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||
mult
|
||||
} else {
|
||||
self.cmd_buf.clear();
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||
return true;
|
||||
};
|
||||
self.set_dirty();
|
||||
self.movement = Some(PageMovement::PageUp(mult));
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(Key::PageDown) => {
|
||||
let mult = if self.cmd_buf.is_empty() {
|
||||
1
|
||||
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
||||
self.cmd_buf.clear();
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||
mult
|
||||
} else {
|
||||
self.cmd_buf.clear();
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||
return true;
|
||||
};
|
||||
self.set_dirty();
|
||||
self.movement = Some(PageMovement::PageDown(mult));
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref key) if *key == Key::Home => {
|
||||
self.set_dirty();
|
||||
self.movement = Some(PageMovement::Home);
|
||||
return true;
|
||||
}
|
||||
UIEvent::Input(ref key) if *key == Key::End => {
|
||||
self.set_dirty();
|
||||
self.movement = Some(PageMovement::End);
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match event {
|
||||
UIEvent::ComponentKill(ref kill_id) if self.mode == ViewMode::View(*kill_id) => {
|
||||
self.mode = ViewMode::List;
|
||||
self.view.take();
|
||||
|
@ -721,6 +822,7 @@ impl Component for ContactList {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,6 @@ struct AccountMenuEntry {
|
|||
// Index in the config account vector.
|
||||
index: usize,
|
||||
}
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub(in crate::listing) struct CachedSearchStrings {
|
||||
subject: String,
|
||||
from: String,
|
||||
body: String,
|
||||
}
|
||||
|
||||
pub trait ListingTrait {
|
||||
fn coordinates(&self) -> (usize, usize, Option<EnvelopeHash>);
|
||||
|
|
|
@ -262,26 +262,22 @@ impl Account {
|
|||
let notify_fn = Arc::new(notify_fn);
|
||||
|
||||
let data_dir = xdg::BaseDirectories::with_profile("meli", &name).unwrap();
|
||||
let address_book = if let Ok(data) = data_dir.place_data_file("addressbook") {
|
||||
let mut address_book = AddressBook::with_account(&settings.account());
|
||||
|
||||
if let Ok(data) = data_dir.place_data_file("addressbook") {
|
||||
if data.exists() {
|
||||
let reader = io::BufReader::new(fs::File::open(data).unwrap());
|
||||
let metadata = reader.get_ref().metadata().unwrap();
|
||||
let mut permissions = metadata.permissions();
|
||||
|
||||
permissions.set_mode(0o600); // Read/write for owner only.
|
||||
reader.get_ref().set_permissions(permissions).unwrap();
|
||||
let result: result::Result<AddressBook, _> = serde_json::from_reader(reader);
|
||||
if let Ok(data_t) = result {
|
||||
data_t
|
||||
} else {
|
||||
AddressBook::new(name.clone())
|
||||
for (id, c) in data_t.cards {
|
||||
if !address_book.card_exists(id) && !c.external_resource() {
|
||||
address_book.add_card(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AddressBook::new(name.clone())
|
||||
}
|
||||
} else {
|
||||
AddressBook::new(name.clone())
|
||||
};
|
||||
|
||||
if settings.account().format() == "imap" {
|
||||
settings.conf.cache_type = crate::conf::CacheType::None;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue