diff --git a/Cargo.toml b/Cargo.toml index 4b6b56a..4c66015 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,9 @@ name = "cosmic-files" version = "0.1.0" authors = ["Jeremy Soller "] -edition = "2021" +edition = "2024" license = "GPL-3.0-only" -rust-version = "1.85.0" +rust-version = "1.85" [build-dependencies] vergen = { version = "8", features = ["git", "gitcl"] } @@ -88,7 +88,7 @@ optional = true git = "https://github.com/pop-os/libcosmic.git" default-features = false #TODO: a11y feature crashes -features = ["autosize","multi-window", "tokio", "winit", "surface-message"] +features = ["autosize", "multi-window", "tokio", "winit", "surface-message"] [features] default = [ diff --git a/cosmic-files-applet/Cargo.toml b/cosmic-files-applet/Cargo.toml index 63097b8..08555f0 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cosmic-files-applet" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] log = "0.4" @@ -11,4 +11,3 @@ zbus = "5" path = ".." default-features = false features = ["desktop", "gvfs", "wayland", "wgpu", "desktop-applet"] - diff --git a/examples/copy.rs b/examples/copy.rs index 296b2d3..f0c3c74 100644 --- a/examples/copy.rs +++ b/examples/copy.rs @@ -1,5 +1,5 @@ use cosmic_files::operation::recursive::Method; -use cosmic_files::operation::{recursive::Context, Controller, ReplaceResult}; +use cosmic_files::operation::{Controller, ReplaceResult, recursive::Context}; use std::{error::Error, io, path::PathBuf}; #[compio::main] diff --git a/examples/dialog.rs b/examples/dialog.rs index 5783e53..303ec29 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -1,8 +1,9 @@ use cosmic::{ + Application, Element, app::{self, Core, Settings, Task}, executor, - iced::{window, Subscription}, - widget, Application, Element, + iced::{Subscription, window}, + widget, }; use cosmic_files::dialog::{ Dialog, DialogChoice, DialogChoiceOption, DialogFilter, DialogFilterPattern, DialogKind, diff --git a/src/app.rs b/src/app.rs index 2b59efd..bafe37f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3,23 +3,24 @@ #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced::{ + Limits, event::wayland::{Event as WaylandEvent, OutputEvent, OverlapNotifyEvent}, platform_specific::runtime::wayland::layer_surface::{ IcedMargin, IcedOutput, SctkLayerSurfaceSettings, }, platform_specific::shell::wayland::commands::layer_surface::{ - destroy_layer_surface, get_layer_surface, Anchor, KeyboardInteractivity, Layer, + Anchor, KeyboardInteractivity, Layer, destroy_layer_surface, get_layer_surface, }, - Limits, }; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced_winit::commands::overlap_notify::overlap_notify; use cosmic::{ - app::{self, context_drawer, Core, Task}, + Application, ApplicationExt, Element, + app::{self, Core, Task, context_drawer}, cosmic_config::{self, ConfigSet}, cosmic_theme, executor, iced::{ - self, + self, Alignment, Event, Length, Point, Rectangle, Size, Subscription, clipboard::dnd::DndAction, core::SmolStr, event, @@ -28,7 +29,6 @@ use cosmic::{ stream, widget::scrollable, window::{self, Event as WindowEvent, Id as WindowId}, - Alignment, Event, Length, Point, Rectangle, Size, Subscription, }, iced_runtime::clipboard, style, surface, theme, @@ -40,13 +40,11 @@ use cosmic::{ segmented_button::{self, Entity}, vertical_space, }, - Application, ApplicationExt, Element, }; use mime_guess::Mime; use notify_debouncer_full::{ - new_debouncer, + DebouncedEvent, Debouncer, FileIdMap, new_debouncer, notify::{self, RecommendedWatcher, Watcher}, - DebouncedEvent, Debouncer, FileIdMap, }; use slotmap::Key as SlotMapKey; use std::{ @@ -65,13 +63,13 @@ use std::{ use tokio::sync::mpsc; use trash::TrashItem; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] -use wayland_client::{protocol::wl_output::WlOutput, Proxy}; +use wayland_client::{Proxy, protocol::wl_output::WlOutput}; use crate::{ clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste}, config::{ - AppTheme, Config, DesktopConfig, Favorite, IconSizes, TabConfig, TimeConfig, TypeToSearch, - TIME_CONFIG_ID, + AppTheme, Config, DesktopConfig, Favorite, IconSizes, TIME_CONFIG_ID, TabConfig, + TimeConfig, TypeToSearch, }, dialog::{Dialog, DialogKind, DialogMessage, DialogResult}, fl, home_dir, @@ -80,14 +78,14 @@ use crate::{ menu, mime_app::{self, MimeApp, MimeAppCache}, mime_icon, - mounter::{MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage, MOUNTERS}, + mounter::{MOUNTERS, MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage}, operation::{ Controller, Operation, OperationError, OperationErrorType, OperationSelection, ReplaceResult, }, spawn_detached::spawn_detached, tab::{ - self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION, SORT_OPTION_FALLBACK, + self, HOVER_DURATION, HeadingOptions, ItemMetadata, Location, SORT_OPTION_FALLBACK, Tab, }, }; use crate::{config::State, dialog::DialogSettings}; @@ -2195,7 +2193,7 @@ impl Application for App { for location in flags.uris { if let Some(e) = app.nav_model.iter().find(|e| { app.nav_model.data::(*e).is_some_and( - |l| matches!(l, Location::Network(ref uri, ..) if *uri == location.to_string()), + |l| matches!(l, Location::Network(uri, ..) if *uri == location.to_string()), ) }) { commands.push(cosmic::task::message(cosmic::Action::App( @@ -3194,7 +3192,11 @@ impl Application for App { } Err(err) => { - log::warn!("failed to reload metadata for {:?}: {}", path, err); + log::warn!( + "failed to reload metadata for {:?}: {}", + path, + err + ); } } //TODO item.thumbnail_opt = @@ -3283,7 +3285,7 @@ impl Application for App { None } }, - )) + )); } Message::OpenInNewWindow(entity_opt) => match env::current_exe() { Ok(exe) => self @@ -3307,7 +3309,7 @@ impl Application for App { self.open_tab(Location::Path(parent), true, Some(vec![path])) }) }, - )) + )); } Message::OpenWithBrowse => match self.dialog_pages.pop_front() { Some(( @@ -4428,14 +4430,14 @@ impl Application for App { } NavMenuAction::OpenInNewTab(entity) => { match self.nav_model.data::(entity) { - Some(Location::Network(ref uri, ref display_name, path)) => { + Some(Location::Network(uri, display_name, path)) => { return self.open_tab( Location::Network(uri.clone(), display_name.clone(), path.clone()), false, None, ); } - Some(Location::Path(ref path)) => { + Some(Location::Path(path)) => { return self.open_tab(Location::Path(path.clone()), false, None); } Some(Location::Recents) => { @@ -5721,7 +5723,7 @@ impl Application for App { .map(|x| Message::TabMessage(Some(*entity), x)), id.clone(), ) - .into() + .into(); } None => widget::text("Unknown tab ID").into(), } @@ -5977,7 +5979,9 @@ impl Application for App { if let Err(e) = futures::executor::block_on(async { output.send(Message::RescanTrash).await }) { - log::warn!("trash needs to be rescanned but sending message failed: {e:?}"); + log::warn!( + "trash needs to be rescanned but sending message failed: {e:?}" + ); } } } @@ -6062,7 +6066,9 @@ impl Application for App { if let Err(e) = futures::executor::block_on(async { output.send(Message::RescanRecents).await }) { - log::warn!("open recents tabs need to be updated but sending message failed: {e:?}"); + log::warn!( + "open recents tabs need to be updated but sending message failed: {e:?}" + ); } } } @@ -6215,7 +6221,7 @@ pub(crate) mod test_utils { }; use log::{debug, trace}; - use tempfile::{tempdir, TempDir}; + use tempfile::{TempDir, tempdir}; use crate::{ config::{IconSizes, TabConfig, ThumbCfg}, @@ -6274,7 +6280,9 @@ pub(crate) mod test_utils { // TempDir won't leak resources as long as the destructor runs let root = tempdir()?; debug!("Root temp directory: {}", root.as_ref().display()); - trace!("Creating {files} files and {hidden} hidden files in {dirs} temp dirs with {nested} nested temp dirs"); + trace!( + "Creating {files} files and {hidden} hidden files in {dirs} temp dirs with {nested} nested temp dirs" + ); // All paths for directories and nested directories let paths = (0..dirs).flat_map(|_| { @@ -6349,11 +6357,7 @@ pub(crate) mod test_utils { Ok(path.read_dir()?.filter_map(|entry| { entry.ok().and_then(|entry| { let path = entry.path(); - if path.is_dir() { - Some(path) - } else { - None - } + if path.is_dir() { Some(path) } else { None } }) })) } diff --git a/src/config.rs b/src/config.rs index 969423f..d66abe8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,9 +3,10 @@ use std::{any::TypeId, num::NonZeroU16, path::PathBuf}; use cosmic::{ - cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry}, + Application, + cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry}, iced::Subscription, - theme, Application, + theme, }; use ordermap::OrderMap; use serde::{Deserialize, Serialize}; diff --git a/src/dialog.rs b/src/dialog.rs index 61ab02d..d78e683 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -2,26 +2,25 @@ // SPDX-License-Identifier: GPL-3.0-only use cosmic::{ - app::{context_drawer, cosmic::Cosmic, Core, Task}, + Application, ApplicationExt, Element, + app::{Core, Task, context_drawer, cosmic::Cosmic}, cosmic_config, cosmic_theme, executor, iced::{ - self, event, + self, Alignment, Event, Length, Size, Subscription, event, futures::{self, SinkExt}, keyboard::{Event as KeyEvent, Key, Modifiers}, - stream, window, Alignment, Event, Length, Size, Subscription, + stream, window, }, theme, widget::{ self, - menu::{key_bind::Modifier, Action as MenuAction, KeyBind}, + menu::{Action as MenuAction, KeyBind, key_bind::Modifier}, segmented_button, }, - Application, ApplicationExt, Element, }; use notify_debouncer_full::{ - new_debouncer, + DebouncedEvent, Debouncer, FileIdMap, new_debouncer, notify::{self, RecommendedWatcher, Watcher}, - DebouncedEvent, Debouncer, FileIdMap, }; use recently_used_xbel::update_recently_used; use std::{ @@ -36,12 +35,12 @@ use std::{ use crate::{ app::{Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind}, - config::{Config, DialogConfig, Favorite, ThumbCfg, TimeConfig, TIME_CONFIG_ID}, + config::{Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig}, fl, home_dir, key_bind::key_binds, localize::LANGUAGE_SORTER, menu, - mounter::{MounterItem, MounterItems, MounterKey, MounterMessage, MOUNTERS}, + mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage}, tab::{self, ItemMetadata, Location, Tab}, }; @@ -1452,7 +1451,11 @@ impl Application for App { } } Err(err) => { - log::warn!("failed to reload metadata for {:?}: {}", path, err); + log::warn!( + "failed to reload metadata for {:?}: {}", + path, + err + ); } } //TODO item.thumbnail_opt = diff --git a/src/localize.rs b/src/localize.rs index 86cced1..f436a61 100644 --- a/src/localize.rs +++ b/src/localize.rs @@ -3,8 +3,8 @@ use std::str::FromStr; use i18n_embed::{ - fluent::{fluent_language_loader, FluentLanguageLoader}, DefaultLocalizer, LanguageLoader, Localizer, + fluent::{FluentLanguageLoader, fluent_language_loader}, }; use icu::locid::Locale; use icu_collator::{Collator, CollatorOptions, Numeric}; diff --git a/src/menu.rs b/src/menu.rs index 145a976..f0b9532 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -1,18 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-only use cosmic::{ + Element, app::Core, iced::{ - advanced::widget::text::Style as TextStyle, keyboard::Modifiers, Alignment, Background, - Border, Length, + Alignment, Background, Border, Length, advanced::widget::text::Style as TextStyle, + keyboard::Modifiers, }, theme, widget::{ - self, button, column, container, divider, horizontal_space, - menu::{self, key_bind::KeyBind, ItemHeight, ItemWidth, MenuBar}, - responsive_menu_bar, text, Row, + self, Row, button, column, container, divider, horizontal_space, + menu::{self, ItemHeight, ItemWidth, MenuBar, key_bind::KeyBind}, + responsive_menu_bar, text, }, - Element, }; use i18n_embed::LanguageLoader; use mime_guess::Mime; diff --git a/src/mime_app.rs b/src/mime_app.rs index d75d26e..e3f8c78 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -346,7 +346,11 @@ impl MimeAppCache { { apps.push(MimeApp::from(app)); } else { - log::info!("failed to add association for {:?}: application {:?} not found", mime, filename); + log::info!( + "failed to add association for {:?}: application {:?} not found", + mime, + filename + ); } } } @@ -385,7 +389,11 @@ impl MimeAppCache { if found { break; } else { - log::debug!("failed to set default for {:?}: application {:?} not found", mime, filename); + log::debug!( + "failed to set default for {:?}: application {:?} not found", + mime, + filename + ); } } } @@ -625,10 +633,12 @@ mod tests { let command = commands.first().unwrap(); assert_eq!("/usr/games/gzdoom", command.get_program().to_str().unwrap()); - assert!(paths - .iter() - .zip(command.get_args()) - .all(|(&expected, actual)| expected == actual.to_string_lossy())); + assert!( + paths + .iter() + .zip(command.get_args()) + .all(|(&expected, actual)| expected == actual.to_string_lossy()) + ); } #[test] @@ -669,10 +679,12 @@ mod tests { assert_eq!(paths.len(), command.get_args().count()); assert_eq!("/usr/bin/mpv", command.get_program().to_str().unwrap()); - assert!(paths - .iter() - .zip(command.get_args()) - .all(|(&expected, actual)| expected == actual.to_string_lossy())); + assert!( + paths + .iter() + .zip(command.get_args()) + .all(|(&expected, actual)| expected == actual.to_string_lossy()) + ); } #[test] @@ -695,11 +707,12 @@ mod tests { assert_eq!(args.len() + paths.len(), command.get_args().count()); assert_eq!("/usr/bin/flatpak", command.get_program().to_str().unwrap()); - assert!(args - .iter() - .chain(paths.iter()) - .zip(command.get_args()) - .all(|(&expected, actual)| expected == actual.to_string_lossy())); + assert!( + args.iter() + .chain(paths.iter()) + .zip(command.get_args()) + .all(|(&expected, actual)| expected == actual.to_string_lossy()) + ); } #[test] @@ -719,10 +732,12 @@ mod tests { "/usr/games/roguelike", command.get_program().to_str().unwrap() ); - assert!(paths - .iter() - .zip(command.get_args()) - .all(|(&expected, actual)| expected == actual.to_string_lossy())); + assert!( + paths + .iter() + .zip(command.get_args()) + .all(|(&expected, actual)| expected == actual.to_string_lossy()) + ); } #[test] @@ -751,11 +766,13 @@ mod tests { ); assert_eq!("/usr/bin/flatpak", command.get_program().to_str().unwrap()); - assert!(args_leading - .iter() - .chain(paths.iter()) - .chain(args_trailing.iter()) - .zip(command.get_args()) - .all(|(&expected, actual)| expected == actual.to_string_lossy())); + assert!( + args_leading + .iter() + .chain(paths.iter()) + .chain(args_trailing.iter()) + .zip(command.get_args()) + .all(|(&expected, actual)| expected == actual.to_string_lossy()) + ); } } diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index 8a42c51..99490f2 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -1,10 +1,11 @@ use cosmic::{ - iced::{futures::SinkExt, stream, Subscription}, - widget, Task, + Task, + iced::{Subscription, futures::SinkExt, stream}, + widget, }; use gio::{glib, prelude::*}; use std::{any::TypeId, cell::Cell, future::pending, path::PathBuf, sync::Arc}; -use tokio::sync::{mpsc, Mutex}; +use tokio::sync::{Mutex, mpsc}; use super::{Mounter, MounterAuth, MounterItem, MounterItems, MounterMessage}; use crate::{ diff --git a/src/mounter/mod.rs b/src/mounter/mod.rs index 9c0a5a3..81bb22b 100644 --- a/src/mounter/mod.rs +++ b/src/mounter/mod.rs @@ -1,4 +1,4 @@ -use cosmic::{iced::Subscription, widget, Task}; +use cosmic::{Task, iced::Subscription, widget}; use once_cell::sync::Lazy; use std::{collections::BTreeMap, fmt, path::PathBuf, sync::Arc}; use tokio::sync::mpsc; diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 89e4a92..b365c59 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -4,7 +4,9 @@ use std::time::Instant; use crate::tab::DOUBLE_CLICK_DURATION; use cosmic::{ + Element, Renderer, Theme, iced_core::{ + Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget, border::Border, event::{self, Event}, layout, @@ -12,11 +14,9 @@ use cosmic::{ overlay, renderer::{self, Quad, Renderer as _}, touch, - widget::{tree, Operation, Tree}, - Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget, + widget::{Operation, Tree, tree}, }, widget::Id, - Element, Renderer, Theme, }; /// Emit messages on mouse events. diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 2dd5343..7d7e525 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -5,7 +5,7 @@ use crate::{ spawn_detached::spawn_detached, tab, }; -use cosmic::iced::futures::{channel::mpsc::Sender, SinkExt}; +use cosmic::iced::futures::{SinkExt, channel::mpsc::Sender}; use std::{ borrow::Cow, fmt::Formatter, @@ -14,7 +14,7 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use tokio::sync::{mpsc, Mutex as TokioMutex}; +use tokio::sync::{Mutex as TokioMutex, mpsc}; use walkdir::WalkDir; use zip::AesMode::Aes256; @@ -140,9 +140,11 @@ async fn copy_or_move( Ok(()) => { log::info!("renamed {from:?} to {to:?}"); false - }, + } Err(err) => { - log::info!("failed to rename {from:?} to {to:?}, fallback to recursive move: {err}"); + log::info!( + "failed to rename {from:?} to {to:?}, fallback to recursive move: {err}" + ); true } } @@ -1155,7 +1157,7 @@ mod tests { path::PathBuf, }; - use cosmic::iced::futures::{channel::mpsc, StreamExt}; + use cosmic::iced::futures::{StreamExt, channel::mpsc}; use log::debug; use test_log::test; use tokio::sync; @@ -1163,11 +1165,11 @@ mod tests { use super::{Controller, Operation, OperationError, OperationSelection, ReplaceResult}; use crate::{ app::{ - test_utils::{ - empty_fs, filter_dirs, filter_files, simple_fs, NAME_LEN, NUM_DIRS, NUM_FILES, - NUM_HIDDEN, NUM_NESTED, - }, DialogPage, Message, + test_utils::{ + NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, empty_fs, filter_dirs, + filter_files, simple_fs, + }, }, fl, }; @@ -1198,10 +1200,13 @@ mod tests { match msg { Message::DialogPush(DialogPage::Replace { tx, .. }) => { debug!("[{id}] Replace request"); - tx.send(ReplaceResult::Cancel).await.expect("Sending a response to a replace request should succeed") - + tx.send(ReplaceResult::Cancel) + .await + .expect("Sending a response to a replace request should succeed") } - _ => unreachable!("Only [ `Message::PendingProgress`, `Message::DialogPush(DialogPage::Replace)` ] are sent from operation"), + _ => unreachable!( + "Only [ `Message::PendingProgress`, `Message::DialogPush(DialogPage::Replace)` ] are sent from operation" + ), } } }; diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index 23f7e53..6802459 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -1,6 +1,6 @@ +use compio::BufResult; use compio::buf::{IntoInner, IoBuf}; use compio::io::{AsyncReadAt, AsyncWriteAt}; -use compio::BufResult; use std::future::Future; use std::pin::Pin; use std::time::Instant; @@ -9,7 +9,7 @@ use walkdir::WalkDir; use crate::operation::OperationError; -use super::{copy_unique_path, Controller, OperationSelection, ReplaceResult}; +use super::{Controller, OperationSelection, ReplaceResult, copy_unique_path}; pub enum Method { Copy, diff --git a/src/tab.rs b/src/tab.rs index 8e2a118..b4ec12d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1,6 +1,16 @@ use cosmic::{ - cosmic_theme, font, + Element, cosmic_theme, font, iced::{ + Alignment, + Border, + Color, + ContentFit, + Length, + Point, + Rectangle, + Size, + Subscription, + Vector, advanced::{ graphics, text::{self, Paragraph}, @@ -17,36 +27,24 @@ use cosmic::{ scrollable::{self, AbsoluteOffset, Viewport}, }, window, - Alignment, - Border, - Color, - ContentFit, - Length, - Point, - Rectangle, - Size, - Subscription, - Vector, }, iced_core::{mouse::ScrollDelta, widget::tree}, theme, widget::{ - self, + self, DndDestination, DndSource, Id, Space, Widget, menu::{action::MenuAction, key_bind::KeyBind}, - DndDestination, DndSource, Id, Space, Widget, }, - Element, }; use chrono::{DateTime, Datelike, Timelike, Utc}; use i18n_embed::LanguageLoader; use icu::datetime::{ - options::{components, preferences}, DateTimeFormatter, DateTimeFormatterOptions, + options::{components, preferences}, }; use image::ImageDecoder; use jxl_oxide::integration::JxlDecoder; -use mime_guess::{mime, Mime}; +use mime_guess::{Mime, mime}; use once_cell::sync::Lazy; use ordermap::OrderMap; use serde::{Deserialize, Serialize}; @@ -62,7 +60,7 @@ use std::{ io::{BufRead, BufReader}, os::unix::fs::MetadataExt, path::{Path, PathBuf}, - sync::{atomic, Arc, LazyLock, Mutex, RwLock}, + sync::{Arc, LazyLock, Mutex, RwLock, atomic}, time::{Duration, Instant, SystemTime}, }; use tempfile::NamedTempFile; @@ -73,7 +71,7 @@ use walkdir::WalkDir; use crate::{ app::{Action, PreviewItem, PreviewKind}, clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste}, - config::{DesktopConfig, IconSizes, TabConfig, ThumbCfg, ICON_SCALE_MAX, ICON_SIZE_GRID}, + config::{DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, ThumbCfg}, dialog::DialogKind, fl, localize::{LANGUAGE_SORTER, LOCALE}, @@ -4020,11 +4018,7 @@ impl Tab { fn column_sort(&self) -> Option> { let check_reverse = |ord: Ordering, sort: bool| { - if sort { - ord - } else { - ord.reverse() - } + if sort { ord } else { ord.reverse() } }; let mut items: Vec<_> = self.items_opt.as_ref()?.iter().enumerate().collect(); let (sort_name, sort_direction, folders_first) = self.sort_options(); @@ -4658,29 +4652,31 @@ impl Tab { pub fn empty_view(&self, has_hidden: bool) -> Element { let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing; - mouse_area::MouseArea::new(widget::column::with_children(vec![widget::container( - widget::column::with_children(match self.mode { - Mode::App | Mode::Dialog(_) => vec![ - widget::icon::from_name("folder-symbolic") - .size(64) - .icon() + mouse_area::MouseArea::new(widget::column::with_children(vec![ + widget::container( + widget::column::with_children(match self.mode { + Mode::App | Mode::Dialog(_) => vec![ + widget::icon::from_name("folder-symbolic") + .size(64) + .icon() + .into(), + widget::text::body(if has_hidden { + fl!("empty-folder-hidden") + } else if matches!(self.location, Location::Search(..)) { + fl!("no-results") + } else { + fl!("empty-folder") + }) .into(), - widget::text::body(if has_hidden { - fl!("empty-folder-hidden") - } else if matches!(self.location, Location::Search(..)) { - fl!("no-results") - } else { - fl!("empty-folder") - }) - .into(), - ], - Mode::Desktop => Vec::new(), - }) - .align_x(Alignment::Center) - .spacing(space_xxs), - ) - .center(Length::Fill) - .into()])) + ], + Mode::Desktop => Vec::new(), + }) + .align_x(Alignment::Center) + .spacing(space_xxs), + ) + .center(Length::Fill) + .into(), + ])) .on_press(|_| Message::Click(None)) .into() } @@ -6109,11 +6105,11 @@ mod tests { use tempfile::TempDir; use test_log::test; - use super::{respond_to_scroll_direction, scan_path, Location, Message, Tab}; + use super::{Location, Message, Tab, respond_to_scroll_direction, scan_path}; use crate::{ app::test_utils::{ - assert_eq_tab_path, empty_fs, eq_path_item, filter_dirs, read_dir_sorted, simple_fs, - tab_click_new, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, + NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, assert_eq_tab_path, empty_fs, + eq_path_item, filter_dirs, read_dir_sorted, simple_fs, tab_click_new, }, config::{IconSizes, TabConfig, ThumbCfg}, }; @@ -6166,12 +6162,16 @@ mod tests { ); // All directories (simple_fs only produces one nested layer) - let dirs: Vec = filter_dirs(path)? - .flat_map(|dir| { - filter_dirs(&dir).map(|nested_dirs| std::iter::once(dir).chain(nested_dirs)) - }) - .flatten() - .collect(); + let dirs: Vec = { + let top_level = filter_dirs(path)?; + let mut result = Vec::new(); + for dir in top_level { + let nested_dirs: Vec = filter_dirs(&dir)?.collect(); + result.push(dir); + result.extend(nested_dirs); + } + result + }; assert!( dirs.len() == NUM_DIRS + NUM_DIRS * NUM_NESTED, "Sanity check: Have {} dirs instead of {}", @@ -6210,10 +6210,12 @@ mod tests { assert_eq!(entries.len(), actual.len()); // Correct files should be scanned - assert!(entries - .into_iter() - .zip(actual.into_iter()) - .all(|(path, item)| eq_path_item(&path, &item))); + assert!( + entries + .into_iter() + .zip(actual.into_iter()) + .all(|(path, item)| eq_path_item(&path, &item)) + ); Ok(()) } @@ -6483,7 +6485,7 @@ mod tests { #[test] fn mode_calculations() { use super::{ - get_mode_part, set_mode_part, MODE_SHIFT_GROUP, MODE_SHIFT_OTHER, MODE_SHIFT_USER, + MODE_SHIFT_GROUP, MODE_SHIFT_OTHER, MODE_SHIFT_USER, get_mode_part, set_mode_part, }; for user in 0..=7 { for group in 0..=7 {