dialog: show configured navbar items and drives, part of #335
This commit is contained in:
parent
15c93cc5b3
commit
ca664f009b
4 changed files with 303 additions and 112 deletions
88
src/app.rs
88
src/app.rs
|
|
@ -46,7 +46,7 @@ use trash::TrashItem;
|
|||
|
||||
use crate::{
|
||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||
config::{AppTheme, Config, Favorite, IconSizes, TabConfig, CONFIG_VERSION},
|
||||
config::{AppTheme, Config, Favorite, IconSizes, TabConfig},
|
||||
fl, home_dir,
|
||||
key_bind::key_binds,
|
||||
localize::LANGUAGE_SORTER,
|
||||
|
|
@ -1041,45 +1041,6 @@ impl Application for App {
|
|||
&mut self.core
|
||||
}
|
||||
|
||||
fn nav_bar(&self) -> Option<Element<message::Message<Self::Message>>> {
|
||||
if !self.core().nav_bar_active() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let nav_model = self.nav_model()?;
|
||||
|
||||
let mut nav = cosmic::widget::nav_bar(nav_model, |entity| {
|
||||
cosmic::app::Message::Cosmic(cosmic::app::cosmic::Message::NavBar(entity))
|
||||
})
|
||||
.drag_id(self.nav_drag_id)
|
||||
.on_dnd_enter(|entity, _| cosmic::app::Message::App(Message::DndEnterNav(entity)))
|
||||
.on_dnd_leave(|_| cosmic::app::Message::App(Message::DndExitNav))
|
||||
.on_dnd_drop(|entity, data, action| {
|
||||
cosmic::app::Message::App(Message::DndDropNav(entity, data, action))
|
||||
})
|
||||
.on_context(|entity| cosmic::app::Message::App(Message::NavBarContext(entity)))
|
||||
.on_close(|entity| cosmic::app::Message::App(Message::NavBarClose(entity)))
|
||||
.on_middle_press(|entity| {
|
||||
cosmic::app::Message::App(Message::NavMenuAction(NavMenuAction::OpenInNewTab(entity)))
|
||||
})
|
||||
.context_menu(self.nav_context_menu(self.nav_bar_context_id))
|
||||
.close_icon(
|
||||
widget::icon::from_name("media-eject-symbolic")
|
||||
.size(16)
|
||||
.icon(),
|
||||
)
|
||||
.into_container();
|
||||
|
||||
if !self.core().is_condensed() {
|
||||
nav = nav.max_width(280);
|
||||
}
|
||||
|
||||
Some(Element::from(
|
||||
// XXX both must be shrink to avoid flex layout from ignoring it
|
||||
nav.width(Length::Shrink).height(Length::Shrink),
|
||||
))
|
||||
}
|
||||
|
||||
/// Creates the application, and optionally emits command on initialize.
|
||||
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
||||
let app_themes = vec![fl!("match-desktop"), fl!("dark"), fl!("light")];
|
||||
|
|
@ -1152,6 +1113,45 @@ impl Application for App {
|
|||
self.window_id_opt.unwrap_or(window::Id::MAIN)
|
||||
}
|
||||
|
||||
fn nav_bar(&self) -> Option<Element<message::Message<Self::Message>>> {
|
||||
if !self.core().nav_bar_active() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let nav_model = self.nav_model()?;
|
||||
|
||||
let mut nav = cosmic::widget::nav_bar(nav_model, |entity| {
|
||||
cosmic::app::Message::Cosmic(cosmic::app::cosmic::Message::NavBar(entity))
|
||||
})
|
||||
.drag_id(self.nav_drag_id)
|
||||
.on_dnd_enter(|entity, _| cosmic::app::Message::App(Message::DndEnterNav(entity)))
|
||||
.on_dnd_leave(|_| cosmic::app::Message::App(Message::DndExitNav))
|
||||
.on_dnd_drop(|entity, data, action| {
|
||||
cosmic::app::Message::App(Message::DndDropNav(entity, data, action))
|
||||
})
|
||||
.on_context(|entity| cosmic::app::Message::App(Message::NavBarContext(entity)))
|
||||
.on_close(|entity| cosmic::app::Message::App(Message::NavBarClose(entity)))
|
||||
.on_middle_press(|entity| {
|
||||
cosmic::app::Message::App(Message::NavMenuAction(NavMenuAction::OpenInNewTab(entity)))
|
||||
})
|
||||
.context_menu(self.nav_context_menu(self.nav_bar_context_id))
|
||||
.close_icon(
|
||||
widget::icon::from_name("media-eject-symbolic")
|
||||
.size(16)
|
||||
.icon(),
|
||||
)
|
||||
.into_container();
|
||||
|
||||
if !self.core().is_condensed() {
|
||||
nav = nav.max_width(280);
|
||||
}
|
||||
|
||||
Some(Element::from(
|
||||
// XXX both must be shrink to avoid flex layout from ignoring it
|
||||
nav.width(Length::Shrink).height(Length::Shrink),
|
||||
))
|
||||
}
|
||||
|
||||
fn nav_context_menu(
|
||||
&self,
|
||||
id: widget::nav_bar::Id,
|
||||
|
|
@ -2797,7 +2797,6 @@ impl Application for App {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
struct ConfigSubscription;
|
||||
struct ThemeSubscription;
|
||||
struct WatcherSubscription;
|
||||
struct TrashWatcherSubscription;
|
||||
|
|
@ -2814,12 +2813,7 @@ impl Application for App {
|
|||
Event::Window(_id, WindowEvent::CloseRequested) => Some(Message::WindowClose),
|
||||
_ => None,
|
||||
}),
|
||||
cosmic_config::config_subscription(
|
||||
TypeId::of::<ConfigSubscription>(),
|
||||
Self::APP_ID.into(),
|
||||
CONFIG_VERSION,
|
||||
)
|
||||
.map(|update| {
|
||||
Config::subscription().map(|update| {
|
||||
if !update.errors.is_empty() {
|
||||
log::info!(
|
||||
"errors loading config {:?}: {:?}",
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::{num::NonZeroU16, path::PathBuf};
|
||||
use std::{any::TypeId, num::NonZeroU16, path::PathBuf};
|
||||
|
||||
use cosmic::{
|
||||
cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry},
|
||||
theme,
|
||||
iced::subscription::Subscription,
|
||||
theme, Application,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::tab::View;
|
||||
|
||||
use super::tab::HeadingOptions;
|
||||
use crate::{
|
||||
app::App,
|
||||
tab::{HeadingOptions, View},
|
||||
};
|
||||
|
||||
pub const CONFIG_VERSION: u64 = 1;
|
||||
|
||||
|
|
@ -97,6 +99,36 @@ pub struct Config {
|
|||
pub tab: TabConfig,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load() -> (Option<cosmic_config::Config>, Self) {
|
||||
match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) {
|
||||
Ok(config_handler) => {
|
||||
let config = match Config::get_entry(&config_handler) {
|
||||
Ok(ok) => ok,
|
||||
Err((errs, config)) => {
|
||||
log::info!("errors loading config: {:?}", errs);
|
||||
config
|
||||
}
|
||||
};
|
||||
(Some(config_handler), config)
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("failed to create config handler: {}", err);
|
||||
(None, Config::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subscription() -> Subscription<cosmic_config::Update<Self>> {
|
||||
struct ConfigSubscription;
|
||||
cosmic_config::config_subscription(
|
||||
TypeId::of::<ConfigSubscription>(),
|
||||
App::APP_ID.into(),
|
||||
CONFIG_VERSION,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
|
|||
265
src/dialog.rs
265
src/dialog.rs
|
|
@ -7,7 +7,7 @@ use cosmic::iced::multi_window::Application as IcedApplication;
|
|||
use cosmic::iced::Application as IcedApplication;
|
||||
use cosmic::{
|
||||
app::{self, cosmic::Cosmic, message, Command, Core},
|
||||
cosmic_theme, executor,
|
||||
cosmic_config, cosmic_theme, executor,
|
||||
iced::{
|
||||
event,
|
||||
futures::{self, SinkExt},
|
||||
|
|
@ -37,8 +37,10 @@ use std::{
|
|||
|
||||
use crate::{
|
||||
app::Action,
|
||||
config::TabConfig,
|
||||
config::{Config, Favorite, TabConfig},
|
||||
fl, home_dir,
|
||||
localize::LANGUAGE_SORTER,
|
||||
mounter::{mounters, MounterItem, MounterItems, MounterKey, Mounters},
|
||||
tab::{self, ItemMetadata, Location, Tab},
|
||||
};
|
||||
|
||||
|
|
@ -152,6 +154,8 @@ impl<M: Send + 'static> Dialog<M> {
|
|||
//TODO: only do this once somehow?
|
||||
crate::localize::localize();
|
||||
|
||||
let (config_handler, config) = Config::load();
|
||||
|
||||
let mut settings = window::Settings::default();
|
||||
settings.decorations = false;
|
||||
settings.exit_on_close_request = false;
|
||||
|
|
@ -181,6 +185,8 @@ impl<M: Send + 'static> Dialog<M> {
|
|||
}
|
||||
}),
|
||||
window_id,
|
||||
config_handler,
|
||||
config,
|
||||
};
|
||||
let (cosmic, cosmic_command) = <Cosmic<App> as IcedApplication>::new((core, flags));
|
||||
|
||||
|
|
@ -279,6 +285,8 @@ struct Flags {
|
|||
kind: DialogKind,
|
||||
path_opt: Option<PathBuf>,
|
||||
window_id: window::Id,
|
||||
config_handler: Option<cosmic_config::Config>,
|
||||
config: Config,
|
||||
}
|
||||
|
||||
/// Messages that are used specifically by our [`App`].
|
||||
|
|
@ -286,9 +294,11 @@ struct Flags {
|
|||
enum Message {
|
||||
Cancel,
|
||||
Choice(usize, usize),
|
||||
Config(Config),
|
||||
Filename(String),
|
||||
Filter(usize),
|
||||
Modifiers(Modifiers),
|
||||
MounterItems(MounterKey, MounterItems),
|
||||
NotifyEvents(Vec<DebouncedEvent>),
|
||||
NotifyWatcher(WatcherWrapper),
|
||||
Open,
|
||||
|
|
@ -297,6 +307,8 @@ enum Message {
|
|||
TabRescan(Vec<tab::Item>),
|
||||
}
|
||||
|
||||
pub struct MounterData(MounterKey, MounterItem);
|
||||
|
||||
struct WatcherWrapper {
|
||||
watcher_opt: Option<Debouncer<RecommendedWatcher, FileIdMap>>,
|
||||
}
|
||||
|
|
@ -330,6 +342,8 @@ struct App {
|
|||
filter_selected: Option<usize>,
|
||||
filename_id: widget::Id,
|
||||
modifiers: Modifiers,
|
||||
mounters: Mounters,
|
||||
mounter_items: HashMap<MounterKey, MounterItems>,
|
||||
nav_model: segmented_button::SingleSelectModel,
|
||||
result_opt: Option<DialogResult>,
|
||||
replace_dialog: bool,
|
||||
|
|
@ -356,6 +370,93 @@ impl App {
|
|||
)
|
||||
}
|
||||
|
||||
fn update_config(&mut self) -> Command<Message> {
|
||||
self.update_nav_model();
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn activate_nav_model_location(&mut self, location: &Location) {
|
||||
let nav_bar_id = self.nav_model.iter().find(|&id| {
|
||||
self.nav_model
|
||||
.data::<Location>(id)
|
||||
.map(|l| l == location)
|
||||
.unwrap_or_default()
|
||||
});
|
||||
|
||||
if let Some(id) = nav_bar_id {
|
||||
self.nav_model.activate(id);
|
||||
} else {
|
||||
let active = self.nav_model.active();
|
||||
segmented_button::Selectable::deactivate(&mut self.nav_model, active);
|
||||
}
|
||||
}
|
||||
|
||||
fn update_nav_model(&mut self) {
|
||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||
|
||||
nav_model = nav_model.insert(|b| {
|
||||
b.text(fl!("recents"))
|
||||
.icon(widget::icon::from_name("accessories-clock-symbolic"))
|
||||
.data(Location::Recents)
|
||||
});
|
||||
|
||||
for (_favorite_i, favorite) in self.flags.config.favorites.iter().enumerate() {
|
||||
if let Some(path) = favorite.path_opt() {
|
||||
let name = if matches!(favorite, Favorite::Home) {
|
||||
fl!("home")
|
||||
} else if let Some(file_name) = path.file_name().and_then(|x| x.to_str()) {
|
||||
file_name.to_string()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
nav_model = nav_model.insert(move |b| {
|
||||
b.text(name.clone())
|
||||
.icon(
|
||||
widget::icon::icon(if path.is_dir() {
|
||||
tab::folder_icon_symbolic(&path, 16)
|
||||
} else {
|
||||
widget::icon::from_name("text-x-generic-symbolic")
|
||||
.size(16)
|
||||
.handle()
|
||||
})
|
||||
.size(16),
|
||||
)
|
||||
.data(Location::Path(path.clone()))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all mounter items
|
||||
let mut nav_items = Vec::new();
|
||||
for (key, items) in self.mounter_items.iter() {
|
||||
for item in items.iter() {
|
||||
nav_items.push((*key, item));
|
||||
}
|
||||
}
|
||||
// Sort by name lexically
|
||||
nav_items.sort_by(|a, b| LANGUAGE_SORTER.compare(&a.1.name(), &b.1.name()));
|
||||
// Add items to nav model
|
||||
for (key, item) in nav_items {
|
||||
nav_model = nav_model.insert(|mut b| {
|
||||
b = b.text(item.name()).data(MounterData(key, item.clone()));
|
||||
if let Some(path) = item.path() {
|
||||
b = b.data(Location::Path(path.clone()));
|
||||
}
|
||||
if let Some(icon) = item.icon() {
|
||||
b = b.icon(widget::icon::icon(icon).size(16));
|
||||
}
|
||||
if item.is_mounted() {
|
||||
b = b.closable();
|
||||
}
|
||||
b
|
||||
});
|
||||
}
|
||||
|
||||
self.nav_model = nav_model.build();
|
||||
|
||||
self.activate_nav_model_location(&self.tab.location.clone());
|
||||
}
|
||||
|
||||
fn update_title(&mut self) -> Command<Message> {
|
||||
self.set_header_title(self.title.clone());
|
||||
self.set_window_title(self.title.clone(), self.main_window_id())
|
||||
|
|
@ -440,40 +541,6 @@ impl Application for App {
|
|||
let title = flags.kind.title();
|
||||
let accept_label = flags.kind.accept_label();
|
||||
|
||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||
|
||||
nav_model = nav_model.insert(move |b| {
|
||||
b.text(fl!("recents"))
|
||||
.icon(widget::icon::from_name("accessories-clock-symbolic").size(16))
|
||||
.data(Location::Recents)
|
||||
});
|
||||
|
||||
if let Some(dir) = dirs::home_dir() {
|
||||
nav_model = nav_model.insert(move |b| {
|
||||
b.text(fl!("home"))
|
||||
.icon(widget::icon::icon(tab::folder_icon_symbolic(&dir, 16)).size(16))
|
||||
.data(Location::Path(dir.clone()))
|
||||
});
|
||||
}
|
||||
//TODO: Sort by name?
|
||||
for dir_opt in &[
|
||||
dirs::document_dir(),
|
||||
dirs::download_dir(),
|
||||
dirs::audio_dir(),
|
||||
dirs::picture_dir(),
|
||||
dirs::video_dir(),
|
||||
] {
|
||||
if let Some(dir) = dir_opt {
|
||||
if let Some(file_name) = dir.file_name().and_then(|x| x.to_str()) {
|
||||
nav_model = nav_model.insert(move |b| {
|
||||
b.text(file_name.to_string())
|
||||
.icon(widget::icon::icon(tab::folder_icon_symbolic(&dir, 16)).size(16))
|
||||
.data(Location::Path(dir.clone()))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let location = Location::Path(match &flags.path_opt {
|
||||
Some(path) => path.to_path_buf(),
|
||||
None => match env::current_dir() {
|
||||
|
|
@ -496,7 +563,9 @@ impl Application for App {
|
|||
filter_selected: None,
|
||||
filename_id: widget::Id::unique(),
|
||||
modifiers: Modifiers::empty(),
|
||||
nav_model: nav_model.build(),
|
||||
mounters: mounters(),
|
||||
mounter_items: HashMap::new(),
|
||||
nav_model: segmented_button::ModelBuilder::default().build(),
|
||||
result_opt: None,
|
||||
replace_dialog: false,
|
||||
tab,
|
||||
|
|
@ -504,7 +573,12 @@ impl Application for App {
|
|||
watcher_opt: None,
|
||||
};
|
||||
|
||||
let commands = Command::batch([app.update_title(), app.update_watcher(), app.rescan_tab()]);
|
||||
let commands = Command::batch([
|
||||
app.update_config(),
|
||||
app.update_title(),
|
||||
app.update_watcher(),
|
||||
app.rescan_tab(),
|
||||
]);
|
||||
|
||||
(app, commands)
|
||||
}
|
||||
|
|
@ -533,6 +607,34 @@ impl Application for App {
|
|||
None
|
||||
}
|
||||
|
||||
fn nav_bar(&self) -> Option<Element<message::Message<Self::Message>>> {
|
||||
if !self.core().nav_bar_active() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let nav_model = self.nav_model()?;
|
||||
|
||||
let mut nav = cosmic::widget::nav_bar(nav_model, |entity| {
|
||||
cosmic::app::Message::Cosmic(cosmic::app::cosmic::Message::NavBar(entity))
|
||||
})
|
||||
//TODO .on_close(|entity| cosmic::app::Message::App(Message::NavBarClose(entity)))
|
||||
.close_icon(
|
||||
widget::icon::from_name("media-eject-symbolic")
|
||||
.size(16)
|
||||
.icon(),
|
||||
)
|
||||
.into_container();
|
||||
|
||||
if !self.core().is_condensed() {
|
||||
nav = nav.max_width(280);
|
||||
}
|
||||
|
||||
Some(Element::from(
|
||||
// XXX both must be shrink to avoid flex layout from ignoring it
|
||||
nav.width(Length::Shrink).height(Length::Shrink),
|
||||
))
|
||||
}
|
||||
|
||||
fn nav_model(&self) -> Option<&segmented_button::SingleSelectModel> {
|
||||
Some(&self.nav_model)
|
||||
}
|
||||
|
|
@ -545,11 +647,17 @@ impl Application for App {
|
|||
fn on_nav_select(&mut self, entity: segmented_button::Entity) -> Command<Message> {
|
||||
let location_opt = self.nav_model.data::<Location>(entity).clone();
|
||||
|
||||
if let Some(location) = location_opt {
|
||||
self.nav_model.activate(entity);
|
||||
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
||||
let message = Message::TabMessage(tab::Message::Location(location.clone()));
|
||||
return self.update(message);
|
||||
}
|
||||
|
||||
if let Some(data) = self.nav_model.data::<MounterData>(entity).clone() {
|
||||
if let Some(mounter) = self.mounters.get(&data.0) {
|
||||
return mounter.mount(data.1.clone()).map(|_| message::none());
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
}
|
||||
|
||||
|
|
@ -584,6 +692,13 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
}
|
||||
Message::Config(config) => {
|
||||
if config != self.flags.config {
|
||||
log::info!("update config");
|
||||
self.flags.config = config;
|
||||
return self.update_config();
|
||||
}
|
||||
}
|
||||
Message::Filename(new_filename) => {
|
||||
// Select based on filename
|
||||
self.tab.select_name(&new_filename);
|
||||
|
|
@ -603,6 +718,52 @@ impl Application for App {
|
|||
Message::Modifiers(modifiers) => {
|
||||
self.modifiers = modifiers;
|
||||
}
|
||||
Message::MounterItems(mounter_key, mounter_items) => {
|
||||
// Check for unmounted folders
|
||||
let mut unmounted = Vec::new();
|
||||
if let Some(old_items) = self.mounter_items.get(&mounter_key) {
|
||||
for old_item in old_items.iter() {
|
||||
if let Some(old_path) = old_item.path() {
|
||||
if old_item.is_mounted() {
|
||||
let mut still_mounted = false;
|
||||
for item in mounter_items.iter() {
|
||||
if let Some(path) = item.path() {
|
||||
if path == old_path {
|
||||
if item.is_mounted() {
|
||||
still_mounted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !still_mounted {
|
||||
unmounted.push(Location::Path(old_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go back to home in any tabs that were unmounted
|
||||
let mut commands = Vec::new();
|
||||
{
|
||||
let home_location = Location::Path(home_dir());
|
||||
if unmounted.contains(&self.tab.location) {
|
||||
self.tab.change_location(&home_location, None);
|
||||
commands.push(self.update_watcher());
|
||||
commands.push(self.rescan_tab());
|
||||
}
|
||||
}
|
||||
|
||||
// Insert new items
|
||||
self.mounter_items.insert(mounter_key, mounter_items);
|
||||
|
||||
// Update nav bar
|
||||
//TODO: this could change favorites IDs while they are in use
|
||||
self.update_nav_model();
|
||||
|
||||
return Command::batch(commands);
|
||||
}
|
||||
Message::NotifyEvents(events) => {
|
||||
log::debug!("{:?}", events);
|
||||
|
||||
|
|
@ -957,14 +1118,23 @@ impl Application for App {
|
|||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
struct WatcherSubscription;
|
||||
|
||||
Subscription::batch([
|
||||
let mut subscriptions = vec![
|
||||
event::listen_with(|event, _status| match event {
|
||||
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
|
||||
Some(Message::Modifiers(modifiers))
|
||||
}
|
||||
_ => None,
|
||||
}),
|
||||
Config::subscription().map(|update| {
|
||||
if !update.errors.is_empty() {
|
||||
log::info!(
|
||||
"errors loading config {:?}: {:?}",
|
||||
update.keys,
|
||||
update.errors
|
||||
);
|
||||
}
|
||||
Message::Config(update.config)
|
||||
}),
|
||||
subscription::channel(
|
||||
TypeId::of::<WatcherSubscription>(),
|
||||
100,
|
||||
|
|
@ -1041,6 +1211,17 @@ impl Application for App {
|
|||
},
|
||||
),
|
||||
self.tab.subscription().map(Message::TabMessage),
|
||||
])
|
||||
];
|
||||
|
||||
for (key, mounter) in self.mounters.iter() {
|
||||
let key = *key;
|
||||
subscriptions.push(
|
||||
mounter
|
||||
.subscription()
|
||||
.map(move |items| Message::MounterItems(key, items)),
|
||||
);
|
||||
}
|
||||
|
||||
Subscription::batch(subscriptions)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/lib.rs
20
src/lib.rs
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
use cosmic::{
|
||||
app::{Application, Settings},
|
||||
cosmic_config::{self, CosmicConfigEntry},
|
||||
iced::Limits,
|
||||
};
|
||||
use std::{path::PathBuf, process};
|
||||
|
|
@ -11,7 +10,7 @@ use std::{path::PathBuf, process};
|
|||
use app::{App, Flags};
|
||||
mod app;
|
||||
pub mod clipboard;
|
||||
use config::{Config, CONFIG_VERSION};
|
||||
use config::Config;
|
||||
mod config;
|
||||
pub mod dialog;
|
||||
mod key_bind;
|
||||
|
|
@ -52,22 +51,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
localize::localize();
|
||||
|
||||
let (config_handler, config) = match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) {
|
||||
Ok(config_handler) => {
|
||||
let config = match Config::get_entry(&config_handler) {
|
||||
Ok(ok) => ok,
|
||||
Err((errs, config)) => {
|
||||
log::info!("errors loading config: {:?}", errs);
|
||||
config
|
||||
}
|
||||
};
|
||||
(Some(config_handler), config)
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("failed to create config handler: {}", err);
|
||||
(None, Config::default())
|
||||
}
|
||||
};
|
||||
let (config_handler, config) = Config::load();
|
||||
|
||||
let mut settings = Settings::default();
|
||||
settings = settings.theme(config.app_theme.theme());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue