mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 09:22:12 +00:00
improved preview
This commit is contained in:
1 parent
b64c192c4f
commit
9033401094
11 files changed
+109
-4
No files matched your search
@@ -228,6 +228,10 @@
|
||||
|
||||
<ContextMenu.Root
|
||||
onOpenChange={(open) => {
|
||||
if (open && fileId !== undefined) {
|
||||
// the file is open for good once its menu is
|
||||
engine.keepPreview([fileId]);
|
||||
}
|
||||
if (open && !selected && kind !== 'root') {
|
||||
select([path]);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
FileStack,
|
||||
FileX,
|
||||
} from '@lucide/svelte';
|
||||
import { getContext } from 'svelte';
|
||||
import { getContext, untrack } from 'svelte';
|
||||
import { i18n } from '$lib/i18n/i18n.svelte';
|
||||
import MetadataDialog from '$lib/components/file-list/metadata/MetadataDialog.svelte';
|
||||
import { editMetadata } from '$lib/components/file-list/metadata/utils.svelte';
|
||||
@@ -94,6 +94,12 @@
|
||||
selected &&
|
||||
selectedElementIds($selection)[0]?.ids[0] === elementId(node)
|
||||
);
|
||||
$effect(() => {
|
||||
// the file is open for good once its info or its appearance is (the desktop app)
|
||||
if (openEditMetadata || openEditStyle) {
|
||||
untrack(() => engine.keepPreview([node.fileId]));
|
||||
}
|
||||
});
|
||||
|
||||
// the desktop app: the files are linked to the file system, they are closed rather than deleted
|
||||
let desktop = $derived($workspace !== undefined);
|
||||
@@ -114,6 +120,8 @@
|
||||
<ContextMenu.Root
|
||||
onOpenChange={(open) => {
|
||||
if (open) {
|
||||
// the file is open for good once its menu is (the desktop app)
|
||||
engine.keepPreview([node.fileId]);
|
||||
if (!selected) {
|
||||
engine.selectNode(node);
|
||||
}
|
||||
|
||||
@@ -69,10 +69,12 @@ export class SortableFileList {
|
||||
setTimeout(() => this.updateToSelection(e), 50),
|
||||
onDeselect: (e: Sortable.SortableEvent) =>
|
||||
setTimeout(() => this.updateToSelection(e), 50),
|
||||
onStart: () => {
|
||||
onStart: (e: Sortable.SortableEvent) => {
|
||||
// all the nodes, not only the elements: the comments are the anchors of the Svelte blocks
|
||||
this._snapshot = Array.from(container.childNodes);
|
||||
dragging.set(sortableLevel);
|
||||
// the files that are dragged (or whose elements are) are open for good
|
||||
engine.keepPreview(this.draggedFiles(e));
|
||||
},
|
||||
onEnd: () => dragging.set(null),
|
||||
onSort: (e: Sortable.SortableEvent) => this.onSort(e),
|
||||
@@ -84,6 +86,17 @@ export class SortableFileList {
|
||||
);
|
||||
}
|
||||
|
||||
/** The files of what is dragged: the dragged files, or the file of the dragged elements. */
|
||||
private draggedFiles(e: Sortable.SortableEvent): string[] {
|
||||
if (this._parent) {
|
||||
return [this._parent.fileId];
|
||||
}
|
||||
const elements: HTMLElement[] = e.items.length > 0 ? e.items : [e.item];
|
||||
return elements
|
||||
.map((element) => element.getAttribute('data-id'))
|
||||
.filter((id): id is string => id !== null);
|
||||
}
|
||||
|
||||
/** The node of a child of the list. */
|
||||
childNode(id: string): FileTreeNode | undefined {
|
||||
const parent = this._parent;
|
||||
|
||||
@@ -212,6 +212,7 @@ export async function createTauriBackend(): Promise<Backend> {
|
||||
workspace: () => invoke<WorkspaceState>('workspace_state'),
|
||||
openFiles: () => invoke<Outcome>('open_files'),
|
||||
openPaths: (paths, preview) => invoke<Outcome>('open_paths', { paths, preview }),
|
||||
keepFiles: (fileIds) => invoke('keep_files', { fileIds }),
|
||||
openFolder: (unsaved) => invoke<Outcome>('open_folder', { unsaved }),
|
||||
closeFolder: (unsaved) => invoke<Outcome>('close_folder', { unsaved }),
|
||||
closeFiles: (fileIds, unsaved) => invoke<Outcome>('close_files', { fileIds, unsaved }),
|
||||
|
||||
@@ -64,6 +64,8 @@ export interface DesktopFiles {
|
||||
* edited or opened for good. Otherwise they are open for good.
|
||||
*/
|
||||
openPaths(paths: string[], preview?: boolean): Promise<Outcome>;
|
||||
/** The files are open for good: the preview among them is not a preview anymore. */
|
||||
keepFiles(fileIds: string[]): Promise<void>;
|
||||
/**
|
||||
* Opens the folder that the user picks, which is watched. Its files are not opened: they are
|
||||
* in its tree (`listFolder`). The folder that was open is closed with its files (see
|
||||
|
||||
@@ -570,6 +570,18 @@ class Engine {
|
||||
return this.addedBy((b) => b.desktop!.openPaths(paths, preview));
|
||||
}
|
||||
|
||||
/**
|
||||
* The files are open for good (the desktop app): the preview among them stays when another file
|
||||
* is opened or selected. The user did something to it, which the engine does not see (opening
|
||||
* its menu or its info, hiding it, dragging it). Nothing is done for the other files.
|
||||
*/
|
||||
async keepPreview(fileIds: string[]) {
|
||||
const workspace = get(this._workspace);
|
||||
if (fileIds.some((id) => workspace?.files[id]?.preview)) {
|
||||
await this.desktopCall((desktop) => desktop.keepFiles(fileIds));
|
||||
}
|
||||
}
|
||||
|
||||
// What the explorer does to the tree of the open folder (the desktop app). When it fails,
|
||||
// `lastError` tells why (a key of the dictionaries, or a message).
|
||||
|
||||
@@ -800,6 +812,7 @@ class Engine {
|
||||
if (!store) {
|
||||
return;
|
||||
}
|
||||
void this.keepPreview([fileId]);
|
||||
const visibility = setHidden(
|
||||
get(store).structure,
|
||||
this._visibility.get(fileId) ?? new Map(),
|
||||
|
||||
Reference in new issue
Block a user