fix: network page entries
This commit is contained in:
parent
a7a519b14c
commit
a37b27e7e4
1 changed files with 74 additions and 9 deletions
|
|
@ -13,6 +13,8 @@ use crate::{
|
||||||
tab::{self, DirSize, ItemMetadata, ItemThumbnail, Location},
|
tab::{self, DirSize, ItemMetadata, ItemThumbnail, Location},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TARGET_URI_ATTRIBUTE: &str = "standard::target-uri";
|
||||||
|
|
||||||
fn gio_icon_to_path(icon: &gio::Icon, size: u16) -> Option<PathBuf> {
|
fn gio_icon_to_path(icon: &gio::Icon, size: u16) -> Option<PathBuf> {
|
||||||
if let Some(themed_icon) = icon.downcast_ref::<gio::ThemedIcon>() {
|
if let Some(themed_icon) = icon.downcast_ref::<gio::ThemedIcon>() {
|
||||||
for name in themed_icon.names() {
|
for name in themed_icon.names() {
|
||||||
|
|
@ -64,7 +66,22 @@ fn items(monitor: &gio::VolumeMonitor, sizes: IconSizes) -> MounterItems {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn network_scan(uri: &str, sizes: IconSizes) -> Result<Vec<tab::Item>, String> {
|
fn network_scan(uri: &str, sizes: IconSizes) -> Result<Vec<tab::Item>, String> {
|
||||||
let file = gio::File::for_uri(uri);
|
let mut uri = uri.to_string();
|
||||||
|
let mut file = gio::File::for_uri(&uri);
|
||||||
|
let force_dir = uri.starts_with("network:///");
|
||||||
|
|
||||||
|
// Resolve the target-uri if it exists
|
||||||
|
if let Ok(file_info) = file.query_info(
|
||||||
|
TARGET_URI_ATTRIBUTE,
|
||||||
|
gio::FileQueryInfoFlags::NONE,
|
||||||
|
gio::Cancellable::NONE,
|
||||||
|
) {
|
||||||
|
if let Some(resolved_uri) = file_info.attribute_as_string(TARGET_URI_ATTRIBUTE) {
|
||||||
|
uri = resolved_uri.to_string();
|
||||||
|
file = gio::File::for_uri(&uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
for info_res in file
|
for info_res in file
|
||||||
.enumerate_children("*", gio::FileQueryInfoFlags::NONE, gio::Cancellable::NONE)
|
.enumerate_children("*", gio::FileQueryInfoFlags::NONE, gio::Cancellable::NONE)
|
||||||
|
|
@ -75,10 +92,43 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result<Vec<tab::Item>, String> {
|
||||||
let display_name = info.display_name().to_string();
|
let display_name = info.display_name().to_string();
|
||||||
|
|
||||||
let uri = file.child(info.name()).uri().to_string();
|
let uri = file.child(info.name()).uri().to_string();
|
||||||
|
|
||||||
//TODO: what is the best way to resolve shortcuts?
|
//TODO: what is the best way to resolve shortcuts?
|
||||||
let location = Location::Network(uri, display_name.clone(), file.child(info.name()).path());
|
let location = Location::Network(uri, display_name.clone(), file.child(&name).path());
|
||||||
//TODO: support dir or file
|
|
||||||
let metadata = ItemMetadata::SimpleDir { entries: 0 };
|
let metadata = if !force_dir && !info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE) {
|
||||||
|
let mtime = info.attribute_uint64(gio::FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||||
|
let is_dir = match info.file_type() {
|
||||||
|
gio::FileType::Directory => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
let size_opt = match is_dir {
|
||||||
|
true => None,
|
||||||
|
false => Some(info.size() as u64),
|
||||||
|
};
|
||||||
|
let mut children_opt = None;
|
||||||
|
|
||||||
|
if is_dir {
|
||||||
|
if let Some(path) = file.child(&name).path() {
|
||||||
|
//TODO: calculate children in the background (and make it cancellable?)
|
||||||
|
match std::fs::read_dir(&path) {
|
||||||
|
Ok(entries) => {
|
||||||
|
children_opt = Some(entries.count());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("failed to read directory {:?}: {}", path, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ItemMetadata::GvfsPath {
|
||||||
|
mtime,
|
||||||
|
size_opt,
|
||||||
|
children_opt,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ItemMetadata::SimpleDir { entries: 0 }
|
||||||
|
};
|
||||||
|
|
||||||
let (mime, icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = {
|
let (mime, icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = {
|
||||||
let file_icon = |size| {
|
let file_icon = |size| {
|
||||||
|
|
@ -397,12 +447,25 @@ impl Gvfs {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Cmd::NetworkScan(uri, sizes, items_tx) => {
|
Cmd::NetworkScan(mut uri, sizes, items_tx) => {
|
||||||
let file = gio::File::for_uri(&uri);
|
let original_uri = uri.clone();
|
||||||
let needs_mount = match file.find_enclosing_mount(gio::Cancellable::NONE) {
|
let mut file = gio::File::for_uri(&uri);
|
||||||
|
if let Ok(file_info) = file.query_info(
|
||||||
|
TARGET_URI_ATTRIBUTE,
|
||||||
|
gio::FileQueryInfoFlags::NONE,
|
||||||
|
gio::Cancellable::NONE,
|
||||||
|
) {
|
||||||
|
if let Some(resolved_uri) = file_info.attribute_as_string(TARGET_URI_ATTRIBUTE) {
|
||||||
|
uri = resolved_uri.to_string();
|
||||||
|
file = gio::File::for_uri(&uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let needs_mount = uri != "network:///" && match file.find_enclosing_mount(gio::Cancellable::NONE) {
|
||||||
Ok(_) => false,
|
Ok(_) => false,
|
||||||
Err(err) => matches!(err.kind::<gio::IOErrorEnum>(), Some(gio::IOErrorEnum::NotMounted))
|
Err(err) => matches!(err.kind::<gio::IOErrorEnum>(), Some(gio::IOErrorEnum::NotMounted))
|
||||||
};
|
};
|
||||||
|
|
||||||
if needs_mount {
|
if needs_mount {
|
||||||
let mount_op = mount_op(uri.clone(), event_tx.clone());
|
let mount_op = mount_op(uri.clone(), event_tx.clone());
|
||||||
let event_tx = event_tx.clone();
|
let event_tx = event_tx.clone();
|
||||||
|
|
@ -412,7 +475,9 @@ impl Gvfs {
|
||||||
gio::Cancellable::NONE,
|
gio::Cancellable::NONE,
|
||||||
move |res| {
|
move |res| {
|
||||||
log::info!("network scan mounted {}: result {:?}", uri, res);
|
log::info!("network scan mounted {}: result {:?}", uri, res);
|
||||||
items_tx.blocking_send(network_scan(&uri, sizes)).unwrap();
|
// FIXME sometimes a uri can be mounted and then not recognized as mounted...
|
||||||
|
// seems to be related to uri with a path
|
||||||
|
items_tx.blocking_send(network_scan(&original_uri, sizes)).unwrap();
|
||||||
event_tx.send(Event::NetworkResult(uri, match res {
|
event_tx.send(Event::NetworkResult(uri, match res {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
|
@ -425,7 +490,7 @@ impl Gvfs {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
items_tx.send(network_scan(&uri, sizes)).await.unwrap();
|
items_tx.send(network_scan(&original_uri, sizes)).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cmd::Unmount(mounter_item) => {
|
Cmd::Unmount(mounter_item) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue