Show cloud files and sync state in the cloud workspace

This commit is contained in:
2026-07-18 18:04:30 -04:00
parent 2383091937
commit 470d8c3d25
8 changed files with 633 additions and 149 deletions
+46
View File
@@ -13,6 +13,7 @@ export interface Settings {
export interface FileEntry {
path: string;
name: string;
is_dir: boolean;
is_text: boolean;
size: number;
}
@@ -96,6 +97,8 @@ export interface BrowseEntry {
space_id: string | null;
last_synced_at: string | null;
child_count: number;
cloud_linked: boolean;
sync_state: "synced" | "pending" | null;
}
export interface TargetInfo {
@@ -125,6 +128,15 @@ export const renameEntry = (path: string, newName: string) =>
export const deleteEntry = (path: string) =>
invoke<void>("delete_entry", { path });
export const moveEntry = (path: string, destination: string) =>
invoke<string>("move_entry", { path, destination });
export const duplicateEntry = (path: string) =>
invoke<string>("duplicate_entry", { path });
export const absolutePath = (path: string) =>
invoke<string>("absolute_path", { path });
export const uploadEntry = (
parent: string,
name: string,
@@ -288,6 +300,20 @@ export const cloudListDocuments = (folderId?: string | null) =>
export const cloudListShared = () => invoke<SharedItems>("cloud_list_shared");
export interface CloudFile {
id: string;
name: string;
mime_type: string;
folder_id: string | null;
created_at: string;
}
export const cloudListFiles = (folderId?: string | null) =>
invoke<CloudFile[]>("cloud_list_files", { folderId: folderId ?? null });
export const cloudDownloadFile = (fileId: string) =>
invoke<string>("cloud_download_file", { fileId });
export const cloudDownloadDocument = (documentId: string, parent: string) =>
invoke<string>("cloud_download_document", { documentId, parent });
@@ -300,6 +326,26 @@ export const cloudResolveDocument = (
serverHash: string,
) => invoke<void>("cloud_resolve_document", { path, content, serverHash });
export interface LinkedDocument {
path: string;
document_id: string;
synced_at: string | null;
sync_state: "synced" | "pending" | null;
}
export interface LinkedSpace {
path: string;
space_id: string;
synced_at: string | null;
sync_state: "synced" | "pending" | null;
}
export const cloudLinkedDocuments = () =>
invoke<LinkedDocument[]>("cloud_linked_documents");
export const cloudLinkedSpaces = () =>
invoke<LinkedSpace[]>("cloud_linked_spaces");
export const cloudDocumentLink = (path: string) =>
invoke<DocumentLink | null>("cloud_document_link", { path });
+47 -3
View File
@@ -3,11 +3,14 @@ import type {
Account,
BrowseEntry,
CloudDocument,
CloudFile,
CloudFolder,
CompileResult,
Conflict,
Diagnostic,
DocumentLink,
LinkedDocument,
LinkedSpace,
Settings,
SpaceSummary,
TargetInfo,
@@ -29,7 +32,10 @@ interface AppState {
cloudFolder: string | null | "shared";
cloudFolders: CloudFolder[];
cloudDocuments: CloudDocument[];
cloudFiles: CloudFile[];
cloudLoading: boolean;
linkedDocuments: LinkedDocument[];
linkedSpaces: LinkedSpace[];
documentLink: DocumentLink | null;
target: TargetInfo | null;
@@ -60,7 +66,10 @@ export const app = $state<AppState>({
cloudFolder: null,
cloudFolders: [],
cloudDocuments: [],
cloudFiles: [],
cloudLoading: false,
linkedDocuments: [],
linkedSpaces: [],
documentLink: null,
target: null,
@@ -163,22 +172,28 @@ export async function refreshCloud() {
app.cloudLoading = true;
try {
app.linkedDocuments = await api.cloudLinkedDocuments().catch(() => []);
app.linkedSpaces = await api.cloudLinkedSpaces().catch(() => []);
if (app.cloudFolder === "shared") {
const shared = await api.cloudListShared();
app.cloudDocuments = shared.documents;
app.spaces = shared.spaces;
app.cloudFolders = [];
app.cloudFiles = [];
} else {
const [folders, documents, spaces] = await Promise.all([
const [folders, documents, spaces, files] = await Promise.all([
api.cloudListFolders(),
api.cloudListDocuments(app.cloudFolder),
api.cloudListSpaces(),
api.cloudListFiles(app.cloudFolder),
]);
app.cloudFolders = folders.filter(
(folder) => (folder.parent_id ?? null) === app.cloudFolder,
);
app.cloudDocuments = documents;
app.spaces = spaces;
app.cloudFiles = files;
}
} catch (error) {
setError(error);
@@ -195,8 +210,7 @@ export async function openCloudFolder(id: string | null | "shared") {
export async function downloadDocument(documentId: string, title: string) {
try {
const path = await api.cloudDownloadDocument(documentId, "");
app.scope = "local";
await browseTo("");
await refreshCloud();
setStatus(`Downloaded '${title}' to this device`);
return path;
} catch (error) {
@@ -205,6 +219,36 @@ export async function downloadDocument(documentId: string, title: string) {
}
}
export function linkedDocument(documentId: string) {
return app.linkedDocuments.find(
(linked) => linked.document_id === documentId,
);
}
export async function downloadCloudFile(fileId: string, name: string) {
try {
await api.cloudDownloadFile(fileId);
setStatus(`'${name}' added to your shared assets`);
} catch (error) {
setError(error);
}
}
export function linkedSpace(spaceId: string) {
return app.linkedSpaces.find((linked) => linked.space_id === spaceId);
}
export async function removeDownloadedDocument(path: string) {
try {
await api.deleteEntry(path);
await api.cloudUnlinkDocument(path);
await refreshCloud();
setStatus("Removed from this device");
} catch (error) {
setError(error);
}
}
export async function openTarget(path: string) {
try {
const target = await api.targetInfo(path);