List Files through get, because query cannot see a folder before 0.16
Creating a folder on the live 0.15.5 server did nothing visible, with no error and nothing after a reload. The folder was real all along: FileNode/query masks its results with document_ids(false) — resources that are *not* containers — so it returns files and never folders, and says nothing about the omission. FileNode/get carries no such mask, so on those servers the whole tree comes from a single get with ids:null instead. That also stops ensureFolder making a fresh "ihasmail" folder on every signature save, having never been able to find the one already there.
This commit is contained in:
+20
-13
@@ -1,6 +1,6 @@
|
||||
import { create } from "zustand";
|
||||
import { CAP, JmapMethodError, client, setErrorMessage } from "@/jmap/client";
|
||||
import { directoryCreate, fileCreate, fileNodeProps, normalizeFileNodes } from "@/lib/filenode";
|
||||
import { directoryCreate, fileCreate, fileNodeProps, normalizeFileNodes, queryOmitsDirectories } from "@/lib/filenode";
|
||||
import type { FileNode, GetResponse, Id, QueryResponse, SetResponse } from "@/jmap/types";
|
||||
import { useSession } from "./session";
|
||||
|
||||
@@ -33,17 +33,24 @@ const byName = (a: FileNode, b: FileNode) => (a.nodeType === b.nodeType ? a.name
|
||||
/** Fetch all nodes (paged, no filter) and rebuild the full children map. */
|
||||
async function loadAllNodes(accountId: Id, set: (fn: (s: FilesState) => Partial<FilesState>) => void): Promise<void> {
|
||||
const all: FileNode[] = [];
|
||||
let position = 0;
|
||||
for (let guard = 0; guard < 100; guard++) {
|
||||
const res = await client.chain([
|
||||
["FileNode/query", { accountId, position, limit: 500, calculateTotal: true }, "q"],
|
||||
["FileNode/get", { accountId, "#ids": { resultOf: "q", name: "FileNode/query", path: "/ids" }, properties: fileNodeProps() }, "g"],
|
||||
]);
|
||||
const q = res.get("q")?.[0] as unknown as QueryResponse;
|
||||
const g = res.get("g")?.[0] as unknown as GetResponse<FileNode>;
|
||||
all.push(...normalizeFileNodes(g.list));
|
||||
position += q.ids.length;
|
||||
if (!q.ids.length || (q.total != null && position >= q.total)) break;
|
||||
if (queryOmitsDirectories()) {
|
||||
// Query would hand back files only, so every folder — including one just
|
||||
// created — would be missing with nothing to say why. Ask get for the lot.
|
||||
const res = await client.call<GetResponse<FileNode>>("FileNode/get", { accountId, ids: null, properties: fileNodeProps() });
|
||||
all.push(...normalizeFileNodes(res.list));
|
||||
} else {
|
||||
let position = 0;
|
||||
for (let guard = 0; guard < 100; guard++) {
|
||||
const res = await client.chain([
|
||||
["FileNode/query", { accountId, position, limit: 500, calculateTotal: true }, "q"],
|
||||
["FileNode/get", { accountId, "#ids": { resultOf: "q", name: "FileNode/query", path: "/ids" }, properties: fileNodeProps() }, "g"],
|
||||
]);
|
||||
const q = res.get("q")?.[0] as unknown as QueryResponse;
|
||||
const g = res.get("g")?.[0] as unknown as GetResponse<FileNode>;
|
||||
all.push(...normalizeFileNodes(g.list));
|
||||
position += q.ids.length;
|
||||
if (!q.ids.length || (q.total != null && position >= q.total)) break;
|
||||
}
|
||||
}
|
||||
const nodes: Record<Id, FileNode> = {};
|
||||
const children: Record<string, Id[]> = { root: [] };
|
||||
@@ -77,7 +84,7 @@ export const useFiles = create<FilesState>((set, get) => ({
|
||||
if (!accountId) return;
|
||||
set({ loading: true });
|
||||
try {
|
||||
if (!filtersSupported) {
|
||||
if (!filtersSupported || queryOmitsDirectories()) {
|
||||
await loadAllNodes(accountId, set);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user