feat: F4.6f3 the file explorer and the image viewer
Oracle FileExplorerWindowRun uses Java's explorer and viewer windows as a person does (the right-click menu, Java's questions answered, the import window, the viewer's open). Both windows work on the document's files through the core's operations: the tree of folders and files, the chosen folder's entries, Java's menu (also as buttons, no right click needed), copy that stays and cut that goes once pasted, the import; the viewer's picture and title. Not taken from Java: a file chosen in the tree taken for a folder, pictures laid over each other, a text file as an empty picture. writeFiles numbers the entries in the file system's order again when a rename made a new key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
import * as Y from 'yjs';
|
||||
import type { Id, VirtualFileContent, VirtualFileSystem } from '@mdg-filius/core';
|
||||
import { VirtualFileSystem as FileSystem } from '@mdg-filius/core';
|
||||
import { fileEntry, fileSystemOf, ROOTS } from './projectDoc.js';
|
||||
import { fileEntry, fileSystemOf, inOrder, ROOTS } from './projectDoc.js';
|
||||
|
||||
export function sameBytes(left: Uint8Array, right: Uint8Array): boolean {
|
||||
return left.length === right.length && left.every((byte, index) => byte === right[index]);
|
||||
@@ -36,7 +36,11 @@ function holds(entry: Y.Map<unknown>, content: VirtualFileContent): boolean {
|
||||
return sameBytes(entry.get('data') as Uint8Array, content.data) && entry.get('mediaType') === content.mediaType;
|
||||
}
|
||||
|
||||
/** A node's files as the file system has them: new ones after the others, changed ones in their place, gone ones removed. */
|
||||
/**
|
||||
* A node's files as the file system has them: new ones after the others,
|
||||
* changed ones in their place, gone ones removed; when the order is no
|
||||
* longer the file system's (a renamed entry), numbered anew.
|
||||
*/
|
||||
export function writeFiles(node: Y.Map<unknown>, fileSystem: VirtualFileSystem): void {
|
||||
let files = node.get('files') as Y.Map<Y.Map<unknown>> | undefined;
|
||||
const wanted: [string, VirtualFileContent][] = [];
|
||||
@@ -65,6 +69,10 @@ export function writeFiles(node: Y.Map<unknown>, fileSystem: VirtualFileSystem):
|
||||
replaceText(entry.get('text') as Y.Text, content.text);
|
||||
}
|
||||
}
|
||||
// An entry renamed is new to the document: the order is the file system's again (a rename keeps the entry's place).
|
||||
if (inOrder(files).some(([path], index) => path !== wanted[index]![0])) {
|
||||
for (const [index, [path]] of wanted.entries()) if (files.get(path)!.get('order') !== index) files.get(path)!.set('order', index);
|
||||
}
|
||||
}
|
||||
|
||||
function nodeMap(doc: Y.Doc, id: Id): Y.Map<unknown> | undefined {
|
||||
|
||||
@@ -116,19 +116,17 @@ describe("a device's files in the document", () => {
|
||||
const order = (fileSystem: VirtualFileSystem) => fileSystem.entriesInCreationOrder('/').map((entry) => entry.path);
|
||||
expect(order(engine)).toEqual(order(nodeFiles(doc, 'pc')!));
|
||||
expect(order(engine).indexOf('/Gross.txt')).toBeLessThan(order(engine).indexOf('/NEU.txt'));
|
||||
// So also in a folder.
|
||||
// So also in a folder: a file renamed there keeps its place, in the document and in the engine.
|
||||
changeFiles(doc, 'pc', 'me', (fileSystem) => {
|
||||
fileSystem.createDirectory('/tief');
|
||||
fileSystem.writeTextFile('/tief/x', 'x');
|
||||
fileSystem.writeTextFile('/tief/y.txt', 'y');
|
||||
});
|
||||
readFilesInto(doc, 'pc', engine);
|
||||
changeFiles(doc, 'pc', 'me', (fileSystem) => {
|
||||
fileSystem.deleteItem('/tief/x');
|
||||
fileSystem.createDirectory('/tief/x');
|
||||
});
|
||||
changeFiles(doc, 'pc', 'me', (fileSystem) => fileSystem.renameInPlace('/tief/x', 'x.txt'));
|
||||
expect(nodeFiles(doc, 'pc')!.entriesInCreationOrder('/tief').map((entry) => entry.path)).toEqual(['/tief/x.txt', '/tief/y.txt']);
|
||||
readFilesInto(doc, 'pc', engine);
|
||||
expect(engine.entriesInCreationOrder('/tief').map((entry) => entry.path)).toEqual(['/tief/x', '/tief/y.txt']);
|
||||
expect(engine.entriesInCreationOrder('/tief').map((entry) => entry.path)).toEqual(['/tief/x.txt', '/tief/y.txt']);
|
||||
});
|
||||
|
||||
it('leave out what the file system refuses, as the editor draws it', () => {
|
||||
|
||||
Reference in New Issue
Block a user