feat(core,fuse,gui): rebuild Trash and shared pages on one file list

The list and grid view from My files moves into widgets/file_list.rs as
FileList, so Trash, Shared with me and Shared by me share its columns,
selection, context menus, keyboard handling and list/grid switch instead of
each drawing its own rows.

Trash shows where each item came from and when it was deleted. Proton does
not expose the trash time through the SDK yet, so the daemon records when it
first sees a node in the trash (migration V35, trash_seen) and reports that;
the date becomes exact once proton-sdk-rs exposes Node::trash_time. Restoring
offers a Show action, and opening a trashed item explains that it needs to be
restored first.

Shared with me splits files and saved links into two views. Files show who
shared them, with a warning pill for unverified senders, the access they give
and when they were shared. Pending invitations sit in a banner that opens a
dialog to accept or decline each one. Several items can be left at once.
Saved links get their own list with open, copy and remove actions.

Shared by me gains a filter (all, links, people, expired links) and columns
for location, people and link state, with a copy button for live links.
Several items can stop being shared at once, the page refreshes after the
share dialog closes, and a reload rebinds only the rows that changed so the
selection survives.

All catalogs are updated and complete.
This commit is contained in:
nvrl committed 2026-09-28 14:35:37 +02:00
1 parent 2339b17d97
commit 127b71efd0
28 files changed
+9501 -6673

No files matched your search

+15 -2
View File
@@ -905,7 +905,7 @@ pub struct ShareEntry {
}
/// A node's public link (in [`Response::Share`] / [`Response::PublicLink`]).
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PublicLinkInfo {
/// Public-link id — the handle for [`Request::RemovePublicLink`].
pub id: String,
@@ -918,6 +918,9 @@ pub struct PublicLinkInfo {
pub expires: Option<i64>,
/// Whether a custom password additionally protects the link.
pub has_password: bool,
/// When the link was made, epoch seconds; 0 when unknown.
#[serde(default)]
pub created: i64,
}
/// One invitation addressed to me (in [`Response::Invitations`]).
@@ -950,7 +953,7 @@ pub struct BookmarkInfo {
/// the share's state so the "Shared" view renders in one pass: how many people
/// have access, how many invitations are still pending, and the public link if
/// the node has one.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct SharedItem {
/// Node uid in `volume~link` form — the handle for opening the node's share
/// (via its mount path) or its details.
@@ -1138,6 +1141,16 @@ pub struct DirEntry {
/// warning worth showing.
#[serde(default)]
pub shared_by_unverified: bool,
/// When a [`Request::ListTrash`] entry went to the trash, epoch seconds; 0
/// when unknown, and for anything not in the trash. The API does not report
/// it to this client, so the daemon notes when it first saw the node there.
#[serde(default)]
pub trashed_at: i64,
/// The folder a [`Request::ListTrash`] entry goes back to on restore, as a
/// mountpoint-relative path (`""` for the root). `None` when that folder is
/// not known, and for anything not in the trash.
#[serde(default)]
pub trashed_from: Option<String>,
}
/// One hit in a [`Request::Search`] result. Like [`DirEntry`] but carries the