mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-13 01:27:03 +01:00
fixed some bugs
This commit is contained in:
1 parent
7766628098
commit
a90cf83ff5
39 files changed
+1573
-1285
No files matched your search
@@ -39,11 +39,10 @@ use pdfs_core::auth;
|
||||
use pdfs_core::config::AppDirs;
|
||||
|
||||
use pdfs_core::control::{
|
||||
ErrorKind,
|
||||
ActivityEntry, ActivityKind, BookmarkInfo, DeviceInfo, DirEntry, InvitationInfo, JobItem,
|
||||
PhotoItem, PhotoKind, PublicLinkInfo, RefreshScope, Request, Response, SearchHit, ShareEntry,
|
||||
ShareEntryKind, SharedItem, SyncFolderInfo, SyncPhase, SyncProgress, TransferDirection,
|
||||
TransferItem, pending_summary, send,
|
||||
ActivityEntry, ActivityKind, BookmarkInfo, DeviceInfo, DirEntry, ErrorKind, InvitationInfo,
|
||||
JobItem, PhotoItem, PhotoKind, PublicLinkInfo, RefreshScope, Request, Response, SearchHit,
|
||||
ShareEntry, ShareEntryKind, SharedItem, SyncFolderInfo, SyncPhase, SyncProgress,
|
||||
TransferDirection, TransferItem, pending_summary, send,
|
||||
};
|
||||
|
||||
use pdfs_core::service;
|
||||
@@ -134,7 +133,8 @@ impl Ui {
|
||||
/// The aspect ratio (w/h) to lay `uid`'s tile out at: the real one once its
|
||||
/// thumbnail has been seen, otherwise [`RATIO_UNKNOWN`].
|
||||
fn ratio(&self, uid: &str) -> f64 {
|
||||
self.gallery.photo_ratio
|
||||
self.gallery
|
||||
.photo_ratio
|
||||
.borrow()
|
||||
.get(uid)
|
||||
.copied()
|
||||
@@ -809,6 +809,7 @@ fn error_headline(kind: ErrorKind, fallback: &str) -> &str {
|
||||
ErrorKind::NotFound => "That's not there any more",
|
||||
ErrorKind::Denied => "You don't have access to that",
|
||||
ErrorKind::Conflict => "Something changed this first",
|
||||
ErrorKind::Quota => "Your Proton Drive is full",
|
||||
ErrorKind::Invalid | ErrorKind::Remote | ErrorKind::Internal => fallback,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,13 @@ pub(crate) fn wire_activity(ui: &Rc<Ui>, retry: >k4::Button) {
|
||||
}
|
||||
|
||||
/// Show a status page in place of the Activity list.
|
||||
pub(crate) fn activity_status(ui: &Rc<Ui>, icon: &str, title: &str, description: &str, retry: bool) {
|
||||
pub(crate) fn activity_status(
|
||||
ui: &Rc<Ui>,
|
||||
icon: &str,
|
||||
title: &str,
|
||||
description: &str,
|
||||
retry: bool,
|
||||
) {
|
||||
ui.activity.status.set_icon_name(Some(icon));
|
||||
ui.activity.status.set_title(title);
|
||||
ui.activity.status.set_description(Some(description));
|
||||
|
||||
@@ -609,7 +609,11 @@ pub(crate) fn stream_entry(ui: &Rc<Ui>, entry: &DirEntry) {
|
||||
let mountpoint = ui.dirs.resolved_mountpoint(&ui.dirs.load_config());
|
||||
let abs = mountpoint.join(&rel);
|
||||
let Some(path) = abs.to_str() else {
|
||||
toast_error(ui, "Couldn't play video", "The file path isn't valid UTF-8.");
|
||||
toast_error(
|
||||
ui,
|
||||
"Couldn't play video",
|
||||
"The file path isn't valid UTF-8.",
|
||||
);
|
||||
return;
|
||||
};
|
||||
toast(ui, &format!("Streaming “{}”…", entry.name));
|
||||
@@ -744,7 +748,8 @@ pub(crate) fn repaint_crumb(ui: &Rc<Ui>, path: &str) {
|
||||
} else {
|
||||
path.split('/').collect()
|
||||
};
|
||||
ui.browser.crumb
|
||||
ui.browser
|
||||
.crumb
|
||||
.append(&crumb_node(ui, "Proton Drive", "", segments.is_empty()));
|
||||
let mut acc = String::new();
|
||||
for (i, seg) in segments.iter().enumerate() {
|
||||
@@ -1071,7 +1076,9 @@ pub(crate) fn start_upload(ui: &Rc<Ui>, sources: Vec<String>) {
|
||||
};
|
||||
toast(&ui, &what);
|
||||
}
|
||||
Ok(Ok(Response::Error { message, kind })) => toast_failure(&ui, "Couldn't upload", &message, kind),
|
||||
Ok(Ok(Response::Error { message, kind })) => {
|
||||
toast_failure(&ui, "Couldn't upload", &message, kind)
|
||||
}
|
||||
_ => toast_error(&ui, "Couldn't upload", "The mount service didn't respond."),
|
||||
}
|
||||
});
|
||||
@@ -1237,7 +1244,11 @@ pub(crate) fn load_browser(ui: &Rc<Ui>) {
|
||||
match result {
|
||||
Ok(Ok(Response::Entries { entries })) => repaint_browser(&ui, &entries),
|
||||
Ok(Ok(Response::Error { message, kind })) => browser_failed(&ui, &message, kind),
|
||||
Ok(Ok(_)) => browser_failed(&ui, "Unexpected reply from the mount service.", ErrorKind::Internal),
|
||||
Ok(Ok(_)) => browser_failed(
|
||||
&ui,
|
||||
"Unexpected reply from the mount service.",
|
||||
ErrorKind::Internal,
|
||||
),
|
||||
Ok(Err(_)) | Err(_) => browser_unreachable(&ui),
|
||||
}
|
||||
});
|
||||
@@ -1374,7 +1385,11 @@ pub(crate) fn run_search(ui: &Rc<Ui>, query: &str) {
|
||||
match result {
|
||||
Ok(Ok(Response::SearchResults { hits })) => repaint_search(&ui, &hits),
|
||||
Ok(Ok(Response::Error { message, kind })) => browser_failed(&ui, &message, kind),
|
||||
Ok(Ok(_)) => browser_failed(&ui, "Unexpected reply from the mount service.", ErrorKind::Internal),
|
||||
Ok(Ok(_)) => browser_failed(
|
||||
&ui,
|
||||
"Unexpected reply from the mount service.",
|
||||
ErrorKind::Internal,
|
||||
),
|
||||
Ok(Err(_)) | Err(_) => browser_unreachable(&ui),
|
||||
}
|
||||
});
|
||||
|
||||
@@ -699,7 +699,12 @@ pub(crate) fn prompt_remove_device(ui: &Rc<Ui>, uid: &str, name: &str) {
|
||||
}
|
||||
|
||||
/// Run a mutation raised from the Devices page and reload the page on success.
|
||||
pub(crate) fn run_devices_mutation(ui: &Rc<Ui>, req: Request, done: &'static str, failed: &'static str) {
|
||||
pub(crate) fn run_devices_mutation(
|
||||
ui: &Rc<Ui>,
|
||||
req: Request,
|
||||
done: &'static str,
|
||||
failed: &'static str,
|
||||
) {
|
||||
ui.busy_begin();
|
||||
let rx = spawn_request(ui.dirs.control_socket(), req);
|
||||
let ui = ui.clone();
|
||||
|
||||
@@ -82,10 +82,12 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
// Pressing Enter in either field submits the form, so signing in never needs
|
||||
// a reach for the mouse. Both fields route to the same button.
|
||||
let btn = ui.login.login_button.clone();
|
||||
ui.login.email
|
||||
ui.login
|
||||
.email
|
||||
.connect_entry_activated(move |_| btn.emit_clicked());
|
||||
let btn = ui.login.login_button.clone();
|
||||
ui.login.password
|
||||
ui.login
|
||||
.password
|
||||
.connect_entry_activated(move |_| btn.emit_clicked());
|
||||
|
||||
let ui = ui.clone();
|
||||
@@ -94,7 +96,9 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
let username = ui.login.email.text().to_string();
|
||||
let password = ui.login.password.text().to_string();
|
||||
if username.is_empty() || password.is_empty() {
|
||||
ui.login.login_status.set_text("Enter your email and password.");
|
||||
ui.login
|
||||
.login_status
|
||||
.set_text("Enter your email and password.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -129,7 +133,10 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
service::enable_start();
|
||||
refresh(&ui);
|
||||
}
|
||||
Err(e) => ui.login.login_status.set_text(&format!("Sign-in failed: {e}")),
|
||||
Err(e) => ui
|
||||
.login
|
||||
.login_status
|
||||
.set_text(&format!("Sign-in failed: {e}")),
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -322,7 +322,10 @@ pub(crate) fn navigate_photo(ui: &Rc<Ui>, viewer: &Rc<Viewer>, delta: i32) {
|
||||
let renderable = |idx: u32| -> Option<PhotoItem> {
|
||||
model
|
||||
.item(idx)
|
||||
.and_then(|obj| obj.downcast_ref::<BoxedAnyObject>().map(|b| b.borrow::<PhotoItem>().clone()))
|
||||
.and_then(|obj| {
|
||||
obj.downcast_ref::<BoxedAnyObject>()
|
||||
.map(|b| b.borrow::<PhotoItem>().clone())
|
||||
})
|
||||
.filter(|photo| photo.kind != PhotoKind::Video)
|
||||
};
|
||||
let scan = |from: i32, step: i32| -> Option<(u32, PhotoItem)> {
|
||||
@@ -564,7 +567,8 @@ pub(crate) fn open_photo_viewer(ui: &Rc<Ui>, initial_uid: String) {
|
||||
let n = ui.gallery.model.n_items();
|
||||
let initial_idx = find_photo_index(&ui.gallery.model, &initial_uid).unwrap_or(0);
|
||||
let capture_time = ui
|
||||
.gallery.model
|
||||
.gallery
|
||||
.model
|
||||
.item(initial_idx)
|
||||
.and_downcast::<BoxedAnyObject>()
|
||||
.map_or(0, |boxed| boxed.borrow::<PhotoItem>().capture_time);
|
||||
|
||||
@@ -356,8 +356,18 @@ pub(crate) fn month_range(year: i32, month: i32) -> Option<(i64, i64)> {
|
||||
|
||||
/// English month names, indexed 1..=12.
|
||||
pub(crate) const MONTH_NAMES: [&str; 12] = [
|
||||
"January", "February", "March", "April", "May", "June", "July", "August", "September",
|
||||
"October", "November", "December",
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
];
|
||||
|
||||
/// Rebuild the date-jump dropdown for the active kind: ask the daemon which
|
||||
@@ -380,7 +390,10 @@ pub(crate) fn refresh_photo_months(ui: &Rc<Ui>) {
|
||||
let mut labels = vec!["All dates".to_string()];
|
||||
let mut ranges: Vec<Option<(i64, i64)>> = vec![None];
|
||||
for m in months {
|
||||
let name = MONTH_NAMES.get((m.month - 1) as usize).copied().unwrap_or("?");
|
||||
let name = MONTH_NAMES
|
||||
.get((m.month - 1) as usize)
|
||||
.copied()
|
||||
.unwrap_or("?");
|
||||
labels.push(format!("{name} {} ({})", m.year, m.count));
|
||||
ranges.push(month_range(m.year, m.month));
|
||||
}
|
||||
@@ -389,7 +402,8 @@ pub(crate) fn refresh_photo_months(ui: &Rc<Ui>) {
|
||||
// Repopulating resets the selection to 0, which would otherwise fire the
|
||||
// handler and reload; suppress that — the caller is already reloading.
|
||||
ui.gallery.date_suppress.set(true);
|
||||
ui.gallery.dates
|
||||
ui.gallery
|
||||
.dates
|
||||
.set_model(Some(>k4::StringList::new(&label_refs)));
|
||||
ui.gallery.dates.set_selected(0);
|
||||
*ui.gallery.date_ranges.borrow_mut() = ranges;
|
||||
@@ -444,7 +458,8 @@ pub(crate) fn wire_gallery(ui: &Rc<Ui>, list: >k4::ListView, scroll: >k4::Sc
|
||||
// re-justify it in place, without rebuilding the ListStore (which would
|
||||
// yank the scroll position back to the top).
|
||||
ui_bind
|
||||
.gallery.bound
|
||||
.gallery
|
||||
.bound
|
||||
.borrow_mut()
|
||||
.insert(item.position(), section);
|
||||
});
|
||||
@@ -456,7 +471,8 @@ pub(crate) fn wire_gallery(ui: &Rc<Ui>, list: >k4::ListView, scroll: >k4::Sc
|
||||
factory.connect_unbind(move |_, item| {
|
||||
let item = item.downcast_ref::<gtk4::ListItem>().unwrap();
|
||||
ui_unbind
|
||||
.gallery.bound
|
||||
.gallery
|
||||
.bound
|
||||
.borrow_mut()
|
||||
.remove(&item.position());
|
||||
if let Some(obj) = item.item().and_downcast::<BoxedAnyObject>() {
|
||||
@@ -562,7 +578,8 @@ pub(crate) fn wire_gallery(ui: &Rc<Ui>, list: >k4::ListView, scroll: >k4::Sc
|
||||
return;
|
||||
}
|
||||
let range = ui_dates
|
||||
.gallery.date_ranges
|
||||
.gallery
|
||||
.date_ranges
|
||||
.borrow()
|
||||
.get(dd.selected() as usize)
|
||||
.copied()
|
||||
@@ -742,7 +759,12 @@ pub(crate) fn plan_rows(ratios: &[f64], target: f64, width: f64) -> Vec<Vec<(i32
|
||||
/// Size one row's tiles at `height`. A `justified` row is nudged so its widths
|
||||
/// plus gaps hit `avail` exactly — rounding each width independently leaves a
|
||||
/// few px of ragged right edge, so the last tile absorbs the remainder.
|
||||
pub(crate) fn size_row(ratios: &[f64], height: f64, avail: f64, justified: bool) -> Vec<(i32, i32)> {
|
||||
pub(crate) fn size_row(
|
||||
ratios: &[f64],
|
||||
height: f64,
|
||||
avail: f64,
|
||||
justified: bool,
|
||||
) -> Vec<(i32, i32)> {
|
||||
let height = height.round().max(1.0);
|
||||
let mut sizes: Vec<(i32, i32)> = ratios
|
||||
.iter()
|
||||
@@ -896,13 +918,15 @@ pub(crate) fn want_thumb(ui: &Rc<Ui>, photo: &PhotoItem, picture: >k4::Picture
|
||||
return;
|
||||
}
|
||||
|
||||
ui.gallery.thumb_wanted
|
||||
ui.gallery
|
||||
.thumb_wanted
|
||||
.borrow_mut()
|
||||
.insert(photo.uid.clone(), picture.clone());
|
||||
|
||||
match photo.thumb_path.as_deref() {
|
||||
Some(path) => {
|
||||
ui.gallery.decode_queue
|
||||
ui.gallery
|
||||
.decode_queue
|
||||
.borrow_mut()
|
||||
.push_back((photo.uid.clone(), path.to_string()));
|
||||
schedule_decode(ui);
|
||||
@@ -1082,7 +1106,8 @@ pub(crate) fn schedule_relayout(ui: &Rc<Ui>) {
|
||||
/// ListView binds them.
|
||||
pub(crate) fn relayout_gallery(ui: &Rc<Ui>) {
|
||||
let bound: Vec<(u32, gtk4::Box)> = ui
|
||||
.gallery.bound
|
||||
.gallery
|
||||
.bound
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(pos, section)| (*pos, section.clone()))
|
||||
@@ -1444,9 +1469,11 @@ pub(crate) fn play_video(ui: &Rc<Ui>, uid: String) {
|
||||
"Couldn't open this video",
|
||||
"Unexpected reply from the mount service.",
|
||||
),
|
||||
Ok(Err(_)) | Err(_) => {
|
||||
toast_error(&ui, "Couldn't open this video", "Couldn't reach Proton Drive.")
|
||||
}
|
||||
Ok(Err(_)) | Err(_) => toast_error(
|
||||
&ui,
|
||||
"Couldn't open this video",
|
||||
"Couldn't reach Proton Drive.",
|
||||
),
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -472,7 +472,12 @@ pub(crate) fn prompt_add_bookmark(ui: &Rc<Ui>) {
|
||||
}
|
||||
|
||||
/// Run a mutation raised from the Shared page and reload the page on success.
|
||||
pub(crate) fn run_shared_mutation(ui: &Rc<Ui>, req: Request, done: &'static str, failed: &'static str) {
|
||||
pub(crate) fn run_shared_mutation(
|
||||
ui: &Rc<Ui>,
|
||||
req: Request,
|
||||
done: &'static str,
|
||||
failed: &'static str,
|
||||
) {
|
||||
ui.busy_begin();
|
||||
let rx = spawn_request(ui.dirs.control_socket(), req);
|
||||
let ui = ui.clone();
|
||||
|
||||
@@ -94,7 +94,13 @@ pub(crate) fn wire_shared_by_me(ui: &Rc<Ui>, retry: >k4::Button) {
|
||||
}
|
||||
|
||||
/// Show a status page in place of the Shared (by-me) list.
|
||||
pub(crate) fn shared_by_me_status(ui: &Rc<Ui>, icon: &str, title: &str, description: &str, retry: bool) {
|
||||
pub(crate) fn shared_by_me_status(
|
||||
ui: &Rc<Ui>,
|
||||
icon: &str,
|
||||
title: &str,
|
||||
description: &str,
|
||||
retry: bool,
|
||||
) {
|
||||
ui.shared_by_me.status.set_icon_name(Some(icon));
|
||||
ui.shared_by_me.status.set_title(title);
|
||||
ui.shared_by_me.status.set_description(Some(description));
|
||||
|
||||
@@ -259,14 +259,20 @@ pub(crate) const GIB: f64 = 1024.0 * 1024.0 * 1024.0;
|
||||
/// read once from config / systemd here (the refresh loop owns only the live
|
||||
/// mount + cache-usage read-out), with [`Ui::settings_suppress`] set around the
|
||||
/// programmatic populate so the change handlers don't fire on it.
|
||||
pub(crate) fn wire_settings(ui: &Rc<Ui>, purge_button: >k4::Button, mountpoint_button: >k4::Button) {
|
||||
pub(crate) fn wire_settings(
|
||||
ui: &Rc<Ui>,
|
||||
purge_button: >k4::Button,
|
||||
mountpoint_button: >k4::Button,
|
||||
) {
|
||||
let config = ui.dirs.load_config();
|
||||
|
||||
// Populate from persisted config + the systemd unit state, suppressed.
|
||||
ui.status.settings_suppress.set(true);
|
||||
ui.status.budget_row
|
||||
ui.status
|
||||
.budget_row
|
||||
.set_value(config.resolved_cache_budget() as f64 / GIB);
|
||||
ui.status.mountpoint_row
|
||||
ui.status
|
||||
.mountpoint_row
|
||||
.set_subtitle(&ui.dirs.resolved_mountpoint(&config).display().to_string());
|
||||
ui.status.autostart_row.set_active(service::is_enabled());
|
||||
ui.status.settings_suppress.set(false);
|
||||
@@ -337,7 +343,12 @@ pub(crate) fn wire_settings(ui: &Rc<Ui>, purge_button: >k4::Button, mountpoint
|
||||
/// confirming with `done` or reporting the daemon's error under `failed`. Unlike
|
||||
/// [`run_mutation`] there's no browser reload; the next refresh tick repaints the
|
||||
/// cache read-out.
|
||||
pub(crate) fn settings_request(ui: &Rc<Ui>, req: Request, done: &'static str, failed: &'static str) {
|
||||
pub(crate) fn settings_request(
|
||||
ui: &Rc<Ui>,
|
||||
req: Request,
|
||||
done: &'static str,
|
||||
failed: &'static str,
|
||||
) {
|
||||
ui.busy_begin();
|
||||
let rx = spawn_request(ui.dirs.control_socket(), req);
|
||||
let ui = ui.clone();
|
||||
@@ -586,7 +597,8 @@ pub(crate) fn repaint_transfers(ui: &Rc<Ui>, items: &[TransferItem], jobs: &[Job
|
||||
.child(&row_box)
|
||||
.build();
|
||||
ui.status.transfers_group.add(&row);
|
||||
ui.status.transfer_rows
|
||||
ui.status
|
||||
.transfer_rows
|
||||
.borrow_mut()
|
||||
.push(TransferRow { row, label, bar });
|
||||
}
|
||||
@@ -742,7 +754,10 @@ pub(crate) fn repaint_pins(ui: &Rc<Ui>, pins: &[pdfs_core::cache::Pin], mounted:
|
||||
.subtitle("Right-click a file in the mount to keep it offline.")
|
||||
.build();
|
||||
ui.status.pins_group.add(&row);
|
||||
ui.status.pin_rows.borrow_mut().push(PinRow { row, unpin: None });
|
||||
ui.status
|
||||
.pin_rows
|
||||
.borrow_mut()
|
||||
.push(PinRow { row, unpin: None });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,10 @@ pub(crate) fn build_details_pane() -> (gtk4::Widget, DetailsWidgets) {
|
||||
/// wire its buttons back onto the entry it's showing.
|
||||
pub(crate) fn wire_details(ui: &Rc<Ui>) {
|
||||
// Both views share one model but have their own selection, so watch both.
|
||||
for selection in [ui.details.grid_selection.clone(), ui.details.list_selection.clone()] {
|
||||
for selection in [
|
||||
ui.details.grid_selection.clone(),
|
||||
ui.details.list_selection.clone(),
|
||||
] {
|
||||
let ui_sel = ui.clone();
|
||||
selection.connect_selection_changed(move |sel, _, _| {
|
||||
match entry_at(sel.model().as_ref(), sel.selected()) {
|
||||
@@ -160,10 +163,12 @@ pub(crate) fn wire_details(ui: &Rc<Ui>) {
|
||||
let ui_close = ui.clone();
|
||||
ui.details.details.close_button.connect_clicked(move |_| {
|
||||
ui_close
|
||||
.details.grid_selection
|
||||
.details
|
||||
.grid_selection
|
||||
.set_selected(gtk4::INVALID_LIST_POSITION);
|
||||
ui_close
|
||||
.details.list_selection
|
||||
.details
|
||||
.list_selection
|
||||
.set_selected(gtk4::INVALID_LIST_POSITION);
|
||||
hide_details(&ui_close);
|
||||
});
|
||||
@@ -193,19 +198,22 @@ pub(crate) fn wire_details(ui: &Rc<Ui>) {
|
||||
}
|
||||
});
|
||||
let ui_pin = ui.clone();
|
||||
ui.details.details.pin_row.connect_active_notify(move |row| {
|
||||
if ui_pin.details.details_suppress.get() {
|
||||
return;
|
||||
}
|
||||
let Some(entry) = ui_pin.details.details_entry.borrow().clone() else {
|
||||
return;
|
||||
};
|
||||
// The switch reads the *desired* state; `toggle_pin` derives the request
|
||||
// from the entry's current one, so only act when they actually differ.
|
||||
if row.is_active() != entry.pinned {
|
||||
toggle_pin(&ui_pin, &entry);
|
||||
}
|
||||
});
|
||||
ui.details
|
||||
.details
|
||||
.pin_row
|
||||
.connect_active_notify(move |row| {
|
||||
if ui_pin.details.details_suppress.get() {
|
||||
return;
|
||||
}
|
||||
let Some(entry) = ui_pin.details.details_entry.borrow().clone() else {
|
||||
return;
|
||||
};
|
||||
// The switch reads the *desired* state; `toggle_pin` derives the request
|
||||
// from the entry's current one, so only act when they actually differ.
|
||||
if row.is_active() != entry.pinned {
|
||||
toggle_pin(&ui_pin, &entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Reveal the details pane and paint it from `entry`.
|
||||
|
||||
@@ -400,7 +400,11 @@ pub(crate) fn repaint_share_link(state: &Rc<ShareDialog>, link: Option<&PublicLi
|
||||
|
||||
/// Create a public link, then reload the dialog so the copy/remove controls
|
||||
/// replace the create form (and the freshly minted URL is shown).
|
||||
pub(crate) fn share_dialog_create_link(state: &Rc<ShareDialog>, role: String, password: Option<String>) {
|
||||
pub(crate) fn share_dialog_create_link(
|
||||
state: &Rc<ShareDialog>,
|
||||
role: String,
|
||||
password: Option<String>,
|
||||
) {
|
||||
let rx = spawn_request(
|
||||
state.ui.dirs.control_socket(),
|
||||
Request::CreatePublicLink {
|
||||
|
||||
@@ -840,9 +840,7 @@ impl Ui {
|
||||
// so it lands on the final list, not a half-populated one.
|
||||
if self.open_pending.get() && self.pending.get() == 0 {
|
||||
self.open_pending.set(false);
|
||||
if let (Some(index), Some(window)) =
|
||||
(self.cursor.get(), self.window.borrow().clone())
|
||||
{
|
||||
if let (Some(index), Some(window)) = (self.cursor.get(), self.window.borrow().clone()) {
|
||||
self.open(index, &window);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user