lexgui 8.1.1 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/Avatar.d.ts +15 -0
- package/build/components/NodeTree.d.ts +51 -26
- package/build/components/Vector.d.ts +10 -9
- package/build/core/Event.d.ts +6 -26
- package/build/core/Namespace.js +1 -1
- package/build/core/Namespace.js.map +1 -1
- package/build/core/Panel.d.ts +538 -538
- package/build/extensions/AssetView.d.ts +7 -6
- package/build/extensions/AssetView.js +194 -155
- package/build/extensions/AssetView.js.map +1 -1
- package/build/extensions/Audio.js.map +1 -1
- package/build/extensions/CodeEditor.d.ts +358 -350
- package/build/extensions/CodeEditor.js +5054 -5022
- package/build/extensions/CodeEditor.js.map +1 -1
- package/build/extensions/DocMaker.js +330 -327
- package/build/extensions/DocMaker.js.map +1 -1
- package/build/extensions/GraphEditor.js +2754 -2760
- package/build/extensions/GraphEditor.js.map +1 -1
- package/build/extensions/Timeline.d.ts +668 -670
- package/build/extensions/Timeline.js +3948 -3955
- package/build/extensions/Timeline.js.map +1 -1
- package/build/extensions/VideoEditor.d.ts +128 -128
- package/build/extensions/VideoEditor.js +893 -898
- package/build/extensions/VideoEditor.js.map +1 -1
- package/build/index.css.d.ts +3 -4
- package/build/index.d.ts +57 -56
- package/build/lexgui.all.js +1587 -1369
- package/build/lexgui.all.js.map +1 -1
- package/build/lexgui.all.min.js +1 -1
- package/build/lexgui.all.module.js +1584 -1364
- package/build/lexgui.all.module.js.map +1 -1
- package/build/lexgui.all.module.min.js +1 -1
- package/build/lexgui.css +6157 -5583
- package/build/lexgui.js +977 -815
- package/build/lexgui.js.map +1 -1
- package/build/lexgui.min.css +2 -3
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +975 -811
- package/build/lexgui.module.js.map +1 -1
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +52 -1
- package/demo.js +167 -65
- package/examples/all-components.html +38 -52
- package/examples/asset-view.html +27 -0
- package/examples/code-editor.html +1 -1
- package/examples/editor.html +10 -95
- package/examples/index.html +2 -2
- package/examples/side-bar.html +1 -1
- package/examples/timeline.html +2 -2
- package/examples/video-editor.html +1 -1
- package/examples/video-editor2.html +2 -2
- package/package.json +7 -4
|
@@ -2,7 +2,8 @@ import { LX } from '../core/Namespace';
|
|
|
2
2
|
declare const Area: any;
|
|
3
3
|
declare const Panel: any;
|
|
4
4
|
declare const NodeTree: any;
|
|
5
|
-
|
|
5
|
+
declare const Tree: any;
|
|
6
|
+
export type AssetViewAction = 'select' | 'dbl_click' | 'check' | 'clone' | 'move' | 'delete' | 'rename' | 'enter_folder' | 'create-folder' | 'refresh-content' | 'node-drag';
|
|
6
7
|
export interface AssetViewItem {
|
|
7
8
|
id: string;
|
|
8
9
|
type: string;
|
|
@@ -23,6 +24,7 @@ interface AssetViewEvent {
|
|
|
23
24
|
where?: AssetViewItem;
|
|
24
25
|
oldName?: string;
|
|
25
26
|
newName?: string;
|
|
27
|
+
search?: any[];
|
|
26
28
|
userInitiated: boolean;
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
@@ -70,9 +72,7 @@ export declare class AssetView {
|
|
|
70
72
|
allowMultipleSelection: boolean;
|
|
71
73
|
previewActions: any[];
|
|
72
74
|
contextMenu: any[];
|
|
73
|
-
onRefreshContent: any;
|
|
74
75
|
itemContextMenuOptions: any;
|
|
75
|
-
onItemDragged: any;
|
|
76
76
|
private _assetsPerPage;
|
|
77
77
|
get assetsPerPage(): any;
|
|
78
78
|
set assetsPerPage(v: any);
|
|
@@ -107,10 +107,11 @@ export declare class AssetView {
|
|
|
107
107
|
_updatePath(): void;
|
|
108
108
|
_createNavigationBar(panel: typeof Panel): void;
|
|
109
109
|
_createTreePanel(area: typeof Area): void;
|
|
110
|
+
_subscribeTreeEvents(tree: typeof Tree): void;
|
|
110
111
|
_setContentLayout(layoutMode: number): void;
|
|
111
112
|
_createContentPanel(area: typeof Area): void;
|
|
112
113
|
_makeNameFilterFn(searchValue: string): (name: string) => boolean;
|
|
113
|
-
_refreshContent(searchValue?: string, filter?: string): void;
|
|
114
|
+
_refreshContent(searchValue?: string, filter?: string, userInitiated?: boolean): void;
|
|
114
115
|
_previewAsset(file: AssetViewItem): void;
|
|
115
116
|
_processDrop(e: DragEvent): void;
|
|
116
117
|
_sortData(sortBy?: string, sortMode?: number): void;
|
|
@@ -124,8 +125,8 @@ export declare class AssetView {
|
|
|
124
125
|
_requestCloneItem(item: AssetViewItem): false | undefined;
|
|
125
126
|
_cloneItem(item: AssetViewItem): AssetViewItem;
|
|
126
127
|
_getClonedName(originalName: string, siblings: any[]): string;
|
|
127
|
-
_requestRenameItem(item: AssetViewItem, newName: string): void;
|
|
128
|
-
_renameItem(item: AssetViewItem, newName: string): void;
|
|
128
|
+
_requestRenameItem(item: AssetViewItem, newName: string, treeEvent?: boolean): void;
|
|
129
|
+
_renameItem(item: AssetViewItem, newName: string, data?: AssetViewItem[]): void;
|
|
129
130
|
_renameItemPopover(item: AssetViewItem): void;
|
|
130
131
|
_requestCreateFolder(folder?: AssetViewItem): void;
|
|
131
132
|
_createFolder(folder?: AssetViewItem): AssetViewItem;
|
|
@@ -9,7 +9,7 @@ LX.extensions.push('AssetView');
|
|
|
9
9
|
const Area = LX.Area;
|
|
10
10
|
LX.Panel;
|
|
11
11
|
LX.NodeTree;
|
|
12
|
-
LX.
|
|
12
|
+
LX.Tree;
|
|
13
13
|
/**
|
|
14
14
|
* @class AssetView
|
|
15
15
|
* @description Asset container with Tree for file system
|
|
@@ -51,9 +51,7 @@ class AssetView {
|
|
|
51
51
|
allowMultipleSelection = false;
|
|
52
52
|
previewActions = [];
|
|
53
53
|
contextMenu = [];
|
|
54
|
-
onRefreshContent = null;
|
|
55
54
|
itemContextMenuOptions = null;
|
|
56
|
-
onItemDragged = null;
|
|
57
55
|
_assetsPerPage = 24;
|
|
58
56
|
get assetsPerPage() {
|
|
59
57
|
return this._assetsPerPage;
|
|
@@ -92,8 +90,6 @@ class AssetView {
|
|
|
92
90
|
this.allowMultipleSelection = options.allowMultipleSelection ?? this.allowMultipleSelection;
|
|
93
91
|
this.previewActions = options.previewActions ?? [];
|
|
94
92
|
this.itemContextMenuOptions = options.itemContextMenuOptions;
|
|
95
|
-
this.onRefreshContent = options.onRefreshContent;
|
|
96
|
-
this.onItemDragged = options.onItemDragged;
|
|
97
93
|
this.gridScale = options.gridScale ?? this.gridScale;
|
|
98
94
|
if (this.gridScale !== 1.0) {
|
|
99
95
|
const r = document.querySelector(':root');
|
|
@@ -154,8 +150,7 @@ class AssetView {
|
|
|
154
150
|
this.currentData = this.data;
|
|
155
151
|
this.path = ['@'];
|
|
156
152
|
if (!this.skipBrowser) {
|
|
157
|
-
this.tree.refresh({ id: '/', children: this.data, type: 'folder',
|
|
158
|
-
metadata: { uid: LX.guidGenerator() } });
|
|
153
|
+
this.tree.refresh({ id: '/', children: this.data, type: 'folder', metadata: { uid: LX.guidGenerator() } });
|
|
159
154
|
}
|
|
160
155
|
this._refreshContent();
|
|
161
156
|
}
|
|
@@ -239,10 +234,8 @@ class AssetView {
|
|
|
239
234
|
});
|
|
240
235
|
itemEl.appendChild(checkbox);
|
|
241
236
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
title.innerText = item.id;
|
|
245
|
-
itemEl.appendChild(title);
|
|
237
|
+
// Asset title
|
|
238
|
+
LX.makeElement('span', 'lexassettitle absolute w-full h-8 bottom-0 text-sm bg-card text-card-foreground cursor-pointer text-center content-center block px-3 py-0.5 truncate z-1 pointer-events-none', item.id, itemEl);
|
|
246
239
|
if (!this.skipPreview) {
|
|
247
240
|
if (item.type === 'video') {
|
|
248
241
|
const itemVideo = LX.makeElement('video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl);
|
|
@@ -330,7 +323,6 @@ class AssetView {
|
|
|
330
323
|
userInitiated: true
|
|
331
324
|
};
|
|
332
325
|
onDblClick(event);
|
|
333
|
-
// event.multiple = !!e.shiftKey;
|
|
334
326
|
}
|
|
335
327
|
else if (!isDoubleClick && onSelect !== undefined) {
|
|
336
328
|
const event = {
|
|
@@ -339,7 +331,6 @@ class AssetView {
|
|
|
339
331
|
userInitiated: true
|
|
340
332
|
};
|
|
341
333
|
onSelect(event);
|
|
342
|
-
// event.multiple = !!e.shiftKey;
|
|
343
334
|
}
|
|
344
335
|
});
|
|
345
336
|
itemEl.addEventListener('contextmenu', function (e) {
|
|
@@ -350,23 +341,21 @@ class AssetView {
|
|
|
350
341
|
const options = [
|
|
351
342
|
{
|
|
352
343
|
name: (multiple > 1) ? (multiple + ' selected') : item.id,
|
|
353
|
-
icon: LX.makeIcon('CircleSmall', { svgClass: `fill-current
|
|
344
|
+
icon: LX.makeIcon('CircleSmall', { svgClass: `fill-current text-${typeColor}` }),
|
|
354
345
|
className: 'text-sm',
|
|
355
346
|
disabled: true
|
|
356
347
|
},
|
|
357
348
|
null
|
|
358
349
|
];
|
|
359
350
|
if (multiple <= 1) {
|
|
360
|
-
options.push({ name: 'Rename', icon: 'TextCursor',
|
|
361
|
-
callback: that._renameItemPopover.bind(that, item) });
|
|
351
|
+
options.push({ name: 'Rename', icon: 'TextCursor', callback: that._renameItemPopover.bind(that, item) });
|
|
362
352
|
}
|
|
363
353
|
if (!isFolder) {
|
|
364
354
|
options.push({ name: 'Clone', icon: 'Copy', callback: that._requestCloneItem.bind(that, item) });
|
|
365
355
|
}
|
|
366
356
|
options.push({ name: 'Move', icon: 'FolderInput', callback: () => that._moveItem(item) });
|
|
367
357
|
if (type == 'Script' && LX.has('CodeEditor')) {
|
|
368
|
-
options.push({ name: 'Open in Editor', icon: 'Code',
|
|
369
|
-
callback: that._openScriptInEditor.bind(that, item) });
|
|
358
|
+
options.push({ name: 'Open in Editor', icon: 'Code', callback: that._openScriptInEditor.bind(that, item) });
|
|
370
359
|
}
|
|
371
360
|
if (that.itemContextMenuOptions) {
|
|
372
361
|
options.push(null);
|
|
@@ -376,7 +365,7 @@ class AssetView {
|
|
|
376
365
|
options.push({ name: o.name, icon: o.icon, callback: o.callback?.bind(that, item) });
|
|
377
366
|
}
|
|
378
367
|
}
|
|
379
|
-
options.push(null, { name: 'Delete', icon: 'Trash2', className: '
|
|
368
|
+
options.push(null, { name: 'Delete', icon: 'Trash2', className: 'text-destructive',
|
|
380
369
|
callback: that._requestDeleteItem.bind(that, item) });
|
|
381
370
|
LX.addClass(that.contentPanel.root, 'pointer-events-none');
|
|
382
371
|
LX.addDropdownMenu(e.target, options, { side: 'right', align: 'start', event: e, onBlur: () => {
|
|
@@ -530,20 +519,20 @@ class AssetView {
|
|
|
530
519
|
return;
|
|
531
520
|
this.nextData.push(this.currentFolder);
|
|
532
521
|
this._enterFolder(this.prevData.pop(), false);
|
|
533
|
-
}, { buttonClass: '
|
|
522
|
+
}, { buttonClass: 'ghost', title: 'Go Back', tooltip: true, icon: 'ArrowLeft' });
|
|
534
523
|
panel.addButton(null, 'GoForwardButton', () => {
|
|
535
524
|
if (!this.nextData.length || !this.currentFolder)
|
|
536
525
|
return;
|
|
537
526
|
this._enterFolder(this.nextData.pop());
|
|
538
|
-
}, { buttonClass: '
|
|
527
|
+
}, { buttonClass: 'ghost', title: 'Go Forward', tooltip: true, icon: 'ArrowRight' });
|
|
539
528
|
panel.addButton(null, 'GoUpButton', () => {
|
|
540
529
|
const parentFolder = this.currentFolder?.parent;
|
|
541
530
|
if (parentFolder)
|
|
542
531
|
this._enterFolder(parentFolder);
|
|
543
|
-
}, { buttonClass: '
|
|
544
|
-
panel.addButton(null, '
|
|
545
|
-
this._refreshContent();
|
|
546
|
-
}, { buttonClass: '
|
|
532
|
+
}, { buttonClass: 'ghost', title: 'Go Upper Folder', tooltip: true, icon: 'ArrowUp' });
|
|
533
|
+
panel.addButton(null, 'RefreshButton', () => {
|
|
534
|
+
this._refreshContent(undefined, undefined, true);
|
|
535
|
+
}, { buttonClass: 'ghost', title: 'Refresh', tooltip: true, icon: 'Refresh' });
|
|
547
536
|
}
|
|
548
537
|
_createTreePanel(area) {
|
|
549
538
|
if (this.leftPanel) {
|
|
@@ -555,61 +544,91 @@ class AssetView {
|
|
|
555
544
|
this._createNavigationBar(this.leftPanel);
|
|
556
545
|
const treeData = { id: '/', children: this.data };
|
|
557
546
|
const tree = this.leftPanel.addTree('Content Browser', treeData, {
|
|
558
|
-
// icons: tree_icons,
|
|
559
547
|
filter: false,
|
|
560
|
-
onlyFolders: this.onlyFolders
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
case LX.TreeEvent.NODE_DRAGGED:
|
|
592
|
-
{
|
|
593
|
-
if (node.parent) {
|
|
594
|
-
const idx = node.parent.children.indexOf(node);
|
|
595
|
-
node.parent.children.splice(idx, 1);
|
|
596
|
-
}
|
|
597
|
-
if (!value.children) {
|
|
598
|
-
value.children = [];
|
|
599
|
-
}
|
|
600
|
-
value.children.push(node);
|
|
601
|
-
node.parent = value;
|
|
602
|
-
node.dir = value.children;
|
|
603
|
-
if (this.onItemDragged) {
|
|
604
|
-
this.onItemDragged(node, value);
|
|
605
|
-
}
|
|
606
|
-
this._refreshContent();
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
548
|
+
onlyFolders: this.onlyFolders
|
|
549
|
+
});
|
|
550
|
+
this._subscribeTreeEvents(tree);
|
|
551
|
+
this.tree = tree.innerTree;
|
|
552
|
+
}
|
|
553
|
+
_subscribeTreeEvents(tree) {
|
|
554
|
+
// If some of these events we don't have to call "resolve" since the AV itself
|
|
555
|
+
// will update the data and refresh when necessary
|
|
556
|
+
tree.on("select", (event, resolve) => {
|
|
557
|
+
if (event.items.length > 1) // Do nothing if multiple selection
|
|
558
|
+
{
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
const node = event.items[0];
|
|
562
|
+
if (!node.parent) {
|
|
563
|
+
if (this.currentFolder) {
|
|
564
|
+
this.prevData.push(this.currentFolder);
|
|
565
|
+
}
|
|
566
|
+
this.currentFolder = undefined;
|
|
567
|
+
this.currentData = this.data;
|
|
568
|
+
this._refreshContent();
|
|
569
|
+
this._updatePath();
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
this._enterFolder(node.type === 'folder' ? node : node.parent);
|
|
573
|
+
this._previewAsset(node);
|
|
574
|
+
if (node.type !== 'folder') {
|
|
575
|
+
this.content.querySelectorAll('.lexassetitem').forEach((i) => i.classList.remove('selected'));
|
|
576
|
+
const dom = node.domEl;
|
|
577
|
+
dom?.classList.add('selected');
|
|
609
578
|
}
|
|
579
|
+
this.selectedItem = node;
|
|
610
580
|
}
|
|
611
581
|
});
|
|
612
|
-
|
|
582
|
+
tree.on("beforeMove", (event, resolve) => {
|
|
583
|
+
const onBeforeNodeDragged = this._callbacks['beforeNodeDragged'];
|
|
584
|
+
const onNodeDragged = this._callbacks['nodeDragged'];
|
|
585
|
+
const node = event.items[0];
|
|
586
|
+
const value = event.to;
|
|
587
|
+
const av_resolve = (...args) => {
|
|
588
|
+
if (node.parent) {
|
|
589
|
+
const idx = node.parent.children.indexOf(node);
|
|
590
|
+
node.parent.children.splice(idx, 1);
|
|
591
|
+
}
|
|
592
|
+
if (!value.children) {
|
|
593
|
+
value.children = [];
|
|
594
|
+
}
|
|
595
|
+
value.children.push(node);
|
|
596
|
+
node.parent = value;
|
|
597
|
+
node.dir = value.children;
|
|
598
|
+
// Resolve Tree move event
|
|
599
|
+
resolve(...args);
|
|
600
|
+
// Fire AV drag event, and not catch the onMove Tree vent
|
|
601
|
+
const av_event = {
|
|
602
|
+
type: 'node-drag',
|
|
603
|
+
items: [node],
|
|
604
|
+
to: value,
|
|
605
|
+
userInitiated: true
|
|
606
|
+
};
|
|
607
|
+
if (onNodeDragged)
|
|
608
|
+
onNodeDragged(av_event, ...args);
|
|
609
|
+
this._refreshContent();
|
|
610
|
+
};
|
|
611
|
+
if (onBeforeNodeDragged) {
|
|
612
|
+
const av_event = {
|
|
613
|
+
type: 'node-drag',
|
|
614
|
+
items: [node],
|
|
615
|
+
to: value,
|
|
616
|
+
userInitiated: true
|
|
617
|
+
};
|
|
618
|
+
onBeforeNodeDragged(av_event, av_resolve);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
av_resolve();
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
tree.on("beforeDelete", (event, resolve) => {
|
|
625
|
+
const node = event.items[0];
|
|
626
|
+
this._requestDeleteItem(node);
|
|
627
|
+
});
|
|
628
|
+
tree.on("beforeRename", (event, resolve) => {
|
|
629
|
+
const node = event.items[0];
|
|
630
|
+
this._requestRenameItem(node, event.newName, true);
|
|
631
|
+
});
|
|
613
632
|
}
|
|
614
633
|
_setContentLayout(layoutMode) {
|
|
615
634
|
this.layout = layoutMode;
|
|
@@ -647,17 +666,14 @@ class AssetView {
|
|
|
647
666
|
{ name: 'Name', icon: 'ALargeSmall', callback: () => this._sortData('id') },
|
|
648
667
|
{ name: 'Type', icon: 'Type', callback: () => this._sortData('type') },
|
|
649
668
|
null,
|
|
650
|
-
{ name: 'Ascending', icon: 'SortAsc',
|
|
651
|
-
|
|
652
|
-
{ name: 'Descending', icon: 'SortDesc',
|
|
653
|
-
callback: () => this._sortData(undefined, AssetView.CONTENT_SORT_DESC) }
|
|
669
|
+
{ name: 'Ascending', icon: 'SortAsc', callback: () => this._sortData(undefined, AssetView.CONTENT_SORT_ASC) },
|
|
670
|
+
{ name: 'Descending', icon: 'SortDesc', callback: () => this._sortData(undefined, AssetView.CONTENT_SORT_DESC) }
|
|
654
671
|
], { side: 'bottom', align: 'start' });
|
|
655
672
|
};
|
|
656
673
|
const _onChangeView = (value, event) => {
|
|
657
674
|
LX.addDropdownMenu(event.target, [
|
|
658
675
|
{ name: 'Grid', icon: 'LayoutGrid', callback: () => this._setContentLayout(AssetView.LAYOUT_GRID) },
|
|
659
|
-
{ name: 'Compact', icon: 'LayoutList',
|
|
660
|
-
callback: () => this._setContentLayout(AssetView.LAYOUT_COMPACT) },
|
|
676
|
+
{ name: 'Compact', icon: 'LayoutList', callback: () => this._setContentLayout(AssetView.LAYOUT_COMPACT) },
|
|
661
677
|
{ name: 'List', icon: 'List', callback: () => this._setContentLayout(AssetView.LAYOUT_LIST) }
|
|
662
678
|
], { side: 'bottom', align: 'start' });
|
|
663
679
|
};
|
|
@@ -669,8 +685,8 @@ class AssetView {
|
|
|
669
685
|
this._createNavigationBar(this.toolsPanel);
|
|
670
686
|
}
|
|
671
687
|
this.toolsPanel.sameLine();
|
|
672
|
-
const sortButton = this.toolsPanel.addButton(null, '', _onSort.bind(this), { title: 'Sort',
|
|
673
|
-
|
|
688
|
+
const sortButton = this.toolsPanel.addButton(null, '', _onSort.bind(this), { title: 'Sort', tooltip: true,
|
|
689
|
+
icon: (this.sortMode === AssetView.CONTENT_SORT_ASC) ? 'SortAsc' : 'SortDesc' });
|
|
674
690
|
this.toolsPanel.addButton(null, '', _onChangeView.bind(this), { title: 'View', tooltip: true,
|
|
675
691
|
icon: (this.layout === AssetView.LAYOUT_GRID) ? 'LayoutGrid' : 'LayoutList' });
|
|
676
692
|
this.toolsPanel.addSelect(null, typeEntries, this.filter ?? typeEntries[0], (v) => {
|
|
@@ -692,7 +708,7 @@ class AssetView {
|
|
|
692
708
|
this.contentPanel.attach(this.content);
|
|
693
709
|
if (!this.skipBrowser) {
|
|
694
710
|
this.contentPanel.addText(null, this.path.join('/'), null, {
|
|
695
|
-
inputClass: 'bg-none
|
|
711
|
+
inputClass: 'bg-none text-muted-foreground text-sm text-end',
|
|
696
712
|
disabled: true,
|
|
697
713
|
signal: '@on_folder_change'
|
|
698
714
|
});
|
|
@@ -741,48 +757,68 @@ class AssetView {
|
|
|
741
757
|
// default case, only check include
|
|
742
758
|
return (name) => name.toLowerCase().includes(q.toLowerCase());
|
|
743
759
|
}
|
|
744
|
-
_refreshContent(searchValue, filter) {
|
|
745
|
-
const
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
const filteredData = this.currentData.filter((_i) => {
|
|
757
|
-
const typeMatch = this.filter !== 'None' ? _i.type.toLowerCase() === this.filter.toLowerCase() : true;
|
|
758
|
-
const nameMatch = nameFilterFn(_i.id);
|
|
759
|
-
return typeMatch && nameMatch;
|
|
760
|
-
});
|
|
761
|
-
this._paginator?.setPages(Math.max(Math.ceil(filteredData.length / this.assetsPerPage), 1));
|
|
762
|
-
// Show all data if using filters
|
|
763
|
-
const start = this._paginator ? (this._paginator.page - 1) * this.assetsPerPage : 0;
|
|
764
|
-
const end = this._paginator ? Math.min(start + this.assetsPerPage, filteredData.length) : filteredData.length;
|
|
765
|
-
for (let i = start; i < end; ++i) {
|
|
766
|
-
let item = filteredData[i];
|
|
767
|
-
if (item.path) {
|
|
768
|
-
LX.request({ url: item.path, dataType: 'blob', success: (f) => {
|
|
769
|
-
item.metadata.bytesize = f.size;
|
|
770
|
-
fr.readAsDataURL(f);
|
|
771
|
-
fr.onload = (e) => {
|
|
772
|
-
const target = e.currentTarget;
|
|
773
|
-
item.src = target.result; // This is a base64 string...
|
|
774
|
-
item.metadata.path = item.path;
|
|
775
|
-
delete item.path;
|
|
776
|
-
this._refreshContent(searchValue, filter);
|
|
777
|
-
};
|
|
778
|
-
} });
|
|
760
|
+
_refreshContent(searchValue, filter, userInitiated = false) {
|
|
761
|
+
const onBeforeRefreshContent = this._callbacks['beforeRefreshContent'];
|
|
762
|
+
const onRefreshContent = this._callbacks['refreshContent'];
|
|
763
|
+
const resolve = (...args) => {
|
|
764
|
+
const isCompactLayout = this.layout == AssetView.LAYOUT_COMPACT;
|
|
765
|
+
const isListLayout = this.layout == AssetView.LAYOUT_LIST;
|
|
766
|
+
this.filter = filter ?? (this.filter ?? 'None');
|
|
767
|
+
this.searchValue = searchValue ?? (this.searchValue ?? '');
|
|
768
|
+
this.content.innerHTML = '';
|
|
769
|
+
this.content.className = `lexassetscontent${isCompactLayout ? ' compact' : (isListLayout ? ' list' : '')}`;
|
|
770
|
+
if (!this.currentData.length) {
|
|
771
|
+
return;
|
|
779
772
|
}
|
|
780
|
-
|
|
781
|
-
|
|
773
|
+
const fr = new FileReader();
|
|
774
|
+
const nameFilterFn = this._makeNameFilterFn(this.searchValue);
|
|
775
|
+
const filteredData = this.currentData.filter((_i) => {
|
|
776
|
+
const typeMatch = this.filter !== 'None' ? _i.type.toLowerCase() === this.filter.toLowerCase() : true;
|
|
777
|
+
const nameMatch = nameFilterFn(_i.id);
|
|
778
|
+
return typeMatch && nameMatch;
|
|
779
|
+
});
|
|
780
|
+
this._paginator?.setPages(Math.max(Math.ceil(filteredData.length / this.assetsPerPage), 1));
|
|
781
|
+
// Show all data if using filters
|
|
782
|
+
const start = this._paginator ? (this._paginator.page - 1) * this.assetsPerPage : 0;
|
|
783
|
+
const end = this._paginator ? Math.min(start + this.assetsPerPage, filteredData.length) : filteredData.length;
|
|
784
|
+
for (let i = start; i < end; ++i) {
|
|
785
|
+
let item = filteredData[i];
|
|
786
|
+
if (item.path) {
|
|
787
|
+
LX.request({ url: item.path, dataType: 'blob', success: (f) => {
|
|
788
|
+
item.metadata.bytesize = f.size;
|
|
789
|
+
fr.readAsDataURL(f);
|
|
790
|
+
fr.onload = (e) => {
|
|
791
|
+
const target = e.currentTarget;
|
|
792
|
+
item.src = target.result; // This is a base64 string...
|
|
793
|
+
item.metadata.path = item.path;
|
|
794
|
+
delete item.path;
|
|
795
|
+
this._refreshContent(searchValue, filter);
|
|
796
|
+
};
|
|
797
|
+
} });
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
item.domEl = this.addItem(item, undefined, false);
|
|
801
|
+
}
|
|
782
802
|
}
|
|
803
|
+
const event = {
|
|
804
|
+
type: 'refresh-content',
|
|
805
|
+
search: [this.searchValue, this.filter],
|
|
806
|
+
items: filteredData.slice(start, end),
|
|
807
|
+
userInitiated
|
|
808
|
+
};
|
|
809
|
+
if (onRefreshContent)
|
|
810
|
+
onRefreshContent(event, ...args);
|
|
811
|
+
};
|
|
812
|
+
if (onBeforeRefreshContent) {
|
|
813
|
+
const event = {
|
|
814
|
+
type: 'refresh-content',
|
|
815
|
+
search: [this.searchValue, this.filter],
|
|
816
|
+
userInitiated
|
|
817
|
+
};
|
|
818
|
+
onBeforeRefreshContent(event, resolve);
|
|
783
819
|
}
|
|
784
|
-
|
|
785
|
-
|
|
820
|
+
else {
|
|
821
|
+
resolve();
|
|
786
822
|
}
|
|
787
823
|
}
|
|
788
824
|
_previewAsset(file) {
|
|
@@ -935,6 +971,7 @@ class AssetView {
|
|
|
935
971
|
if (mustRefresh) {
|
|
936
972
|
this._processData(this.data);
|
|
937
973
|
this._refreshContent();
|
|
974
|
+
this.tree?.select(this.currentFolder.id);
|
|
938
975
|
}
|
|
939
976
|
this._updatePath();
|
|
940
977
|
}
|
|
@@ -1037,6 +1074,7 @@ class AssetView {
|
|
|
1037
1074
|
this.tree?.refresh();
|
|
1038
1075
|
this._moveItemDialog?.destroy();
|
|
1039
1076
|
this._movingItem = undefined;
|
|
1077
|
+
this.previewPanel?.clear();
|
|
1040
1078
|
}
|
|
1041
1079
|
_moveItem(item, defaultFolder) {
|
|
1042
1080
|
if (this._moveItemDialog) {
|
|
@@ -1051,16 +1089,16 @@ class AssetView {
|
|
|
1051
1089
|
for (let pi of (targetFolder.children ?? targetFolder)) {
|
|
1052
1090
|
const row = LX.makeContainer(['100%', 'auto'], 'flex flex-row px-1 items-center', '', container);
|
|
1053
1091
|
const isFolder = pi.type === 'folder';
|
|
1054
|
-
const rowItem = LX.makeContainer(['100%', 'auto'], `move-item flex flex-row gap-1 py-1 px-3 cursor-pointer ${isFolder ? '
|
|
1092
|
+
const rowItem = LX.makeContainer(['100%', 'auto'], `move-item flex flex-row gap-1 py-1 px-3 cursor-pointer items-center ${isFolder ? 'text-foreground font-medium' : 'text-muted-foreground'} rounded-2xl ${isFolder ? 'hover:bg-accent' : 'hover:bg-muted'}`, `${isFolder ? LX.makeIcon('FolderOpen', { svgClass: '' }).innerHTML : ''}${pi.id}`, row);
|
|
1055
1093
|
if (isFolder) {
|
|
1056
1094
|
rowItem.addEventListener('click', () => {
|
|
1057
|
-
container.querySelectorAll('.move-item').forEach((el) => LX.removeClass(el, 'bg-
|
|
1058
|
-
LX.addClass(rowItem, 'bg-
|
|
1095
|
+
container.querySelectorAll('.move-item').forEach((el) => LX.removeClass(el, 'bg-primary text-primary-foreground'));
|
|
1096
|
+
LX.addClass(rowItem, 'bg-primary text-primary-foreground');
|
|
1059
1097
|
targetFolder = pi;
|
|
1060
1098
|
});
|
|
1061
1099
|
const fPathButton = new LX.Button(null, 'FPathButton', () => {
|
|
1062
1100
|
_openFolder(pi, container);
|
|
1063
|
-
}, { icon: 'ChevronRight', className: 'ml-auto h-8', buttonClass: '
|
|
1101
|
+
}, { icon: 'ChevronRight', className: 'ml-auto h-8', buttonClass: 'ghost' });
|
|
1064
1102
|
row.appendChild(fPathButton.root);
|
|
1065
1103
|
}
|
|
1066
1104
|
}
|
|
@@ -1094,33 +1132,29 @@ class AssetView {
|
|
|
1094
1132
|
p.attach(area);
|
|
1095
1133
|
const content = LX.makeContainer(['auto', '100%'], 'flex flex-auto-fill flex-col overflow-scroll py-2 gap-1', ``);
|
|
1096
1134
|
{
|
|
1097
|
-
const headerPanel = area.addPanel({ className: 'p-2 border-
|
|
1135
|
+
const headerPanel = area.addPanel({ className: 'p-2 border-b-color flex flex-auto-keep', height: 'auto' });
|
|
1098
1136
|
headerPanel.sameLine(2, 'w-full');
|
|
1099
1137
|
headerPanel.addButton(null, 'BackButton', () => {
|
|
1100
1138
|
if (targetFolder && targetFolder.parent)
|
|
1101
1139
|
_openFolder(targetFolder.parent, content);
|
|
1102
|
-
}, { icon: 'ArrowLeft', title: 'Back', tooltip: true, className: 'flex-auto',
|
|
1103
|
-
buttonClass: 'bg-none hover:bg-secondary' });
|
|
1140
|
+
}, { icon: 'ArrowLeft', title: 'Back', tooltip: true, className: 'flex-auto-keep', buttonClass: 'ghost' });
|
|
1104
1141
|
bcContainer = LX.makeElement('div');
|
|
1105
|
-
headerPanel.addContent('ITEM_MOVE_PATH', bcContainer, { signal: '@item_move_path',
|
|
1106
|
-
className: 'flex-auto-fill' });
|
|
1142
|
+
headerPanel.addContent('ITEM_MOVE_PATH', bcContainer, { signal: '@item_move_path', className: 'flex-auto-fill' });
|
|
1107
1143
|
}
|
|
1108
1144
|
area.attach(content);
|
|
1109
1145
|
_openFolder(defaultFolder ?? this.data, content);
|
|
1110
1146
|
{
|
|
1111
|
-
const footerPanel = area.addPanel({ className: 'p-2 border-
|
|
1112
|
-
height: 'auto' });
|
|
1147
|
+
const footerPanel = area.addPanel({ className: 'p-2 border-t-color flex flex-auto-keep justify-between', height: 'auto' });
|
|
1113
1148
|
footerPanel.addButton(null, 'NewFolderButton', () => {
|
|
1114
1149
|
this._requestCreateFolder(targetFolder);
|
|
1115
|
-
}, { width: 'auto', icon: 'FolderPlus', title: 'Create Folder', tooltip: true, className: 'ml-2',
|
|
1116
|
-
buttonClass: 'bg-none hover:bg-secondary' });
|
|
1150
|
+
}, { width: 'auto', icon: 'FolderPlus', title: 'Create Folder', tooltip: true, className: 'ml-2', buttonClass: 'ghost' });
|
|
1117
1151
|
footerPanel.sameLine(2, 'mr-2');
|
|
1118
1152
|
footerPanel.addButton(null, 'Cancel', () => {
|
|
1119
1153
|
this._moveItemDialog.close();
|
|
1120
|
-
}, { buttonClass: '
|
|
1154
|
+
}, { buttonClass: 'ghost text-destructive' });
|
|
1121
1155
|
footerPanel.addButton(null, 'Move', () => {
|
|
1122
1156
|
this._requestMoveItemToFolder(item, targetFolder);
|
|
1123
|
-
}, { className: '', buttonClass: '
|
|
1157
|
+
}, { className: '', buttonClass: 'primary' });
|
|
1124
1158
|
}
|
|
1125
1159
|
}, { modal: true, size: ['616px', '500px'], closable: true, onBeforeClose: () => {
|
|
1126
1160
|
delete this._moveItemDialog;
|
|
@@ -1218,12 +1252,12 @@ class AssetView {
|
|
|
1218
1252
|
}
|
|
1219
1253
|
return maxN === -1 ? originalName : `${base} (${maxN + 1})${ext}`;
|
|
1220
1254
|
}
|
|
1221
|
-
_requestRenameItem(item, newName) {
|
|
1255
|
+
_requestRenameItem(item, newName, treeEvent = false) {
|
|
1222
1256
|
const onBeforeRename = this._callbacks['beforeRename'];
|
|
1223
1257
|
const onRename = this._callbacks['rename'];
|
|
1224
1258
|
const oldName = item.id;
|
|
1225
1259
|
const resolve = (...args) => {
|
|
1226
|
-
this._renameItem(item, newName);
|
|
1260
|
+
this._renameItem(item, newName, treeEvent ? item.dir : this.currentData);
|
|
1227
1261
|
const event = {
|
|
1228
1262
|
type: 'rename',
|
|
1229
1263
|
items: [item],
|
|
@@ -1248,21 +1282,25 @@ class AssetView {
|
|
|
1248
1282
|
resolve();
|
|
1249
1283
|
}
|
|
1250
1284
|
}
|
|
1251
|
-
_renameItem(item, newName) {
|
|
1252
|
-
|
|
1285
|
+
_renameItem(item, newName, data) {
|
|
1286
|
+
data = data ?? this.currentData;
|
|
1287
|
+
const idx = data.indexOf(item);
|
|
1253
1288
|
if (idx < 0) {
|
|
1254
1289
|
return;
|
|
1255
1290
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
hoverTitle.
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1291
|
+
// It could be a Tree event, so maybe the elements is not created yet
|
|
1292
|
+
if (item.domEl) {
|
|
1293
|
+
const wasSelected = LX.hasClass(item.domEl, 'selected');
|
|
1294
|
+
const hoverTitle = this.content.querySelector(`#floatingTitle_${item.id.replace(/\s/g, '_').replaceAll('.', '_')}`);
|
|
1295
|
+
if (hoverTitle)
|
|
1296
|
+
hoverTitle.remove();
|
|
1297
|
+
item.domEl?.remove();
|
|
1298
|
+
item.domEl = this.addItem(item, idx * 2);
|
|
1299
|
+
if (wasSelected) {
|
|
1300
|
+
this._previewAsset(item);
|
|
1301
|
+
}
|
|
1265
1302
|
}
|
|
1303
|
+
item.id = newName;
|
|
1266
1304
|
this.tree?.refresh();
|
|
1267
1305
|
this._processData(this.data);
|
|
1268
1306
|
}
|
|
@@ -1284,7 +1322,7 @@ class AssetView {
|
|
|
1284
1322
|
});
|
|
1285
1323
|
panel.addButton(null, 'Save', () => {
|
|
1286
1324
|
onRename(newName);
|
|
1287
|
-
}, { buttonClass: '
|
|
1325
|
+
}, { buttonClass: 'primary' });
|
|
1288
1326
|
const p = new LX.Popover(item.domEl, [panel], { align: 'center', side: 'bottom', sideOffset: -128 });
|
|
1289
1327
|
}
|
|
1290
1328
|
_requestCreateFolder(folder) {
|
|
@@ -1322,14 +1360,15 @@ class AssetView {
|
|
|
1322
1360
|
if (!folder) {
|
|
1323
1361
|
throw ('_createFolder: Something went wrong!');
|
|
1324
1362
|
}
|
|
1363
|
+
const dir = folder.children ?? folder;
|
|
1325
1364
|
const newFolder = {
|
|
1326
|
-
id: this._getClonedName('New Folder',
|
|
1365
|
+
id: this._getClonedName('New Folder', dir),
|
|
1327
1366
|
type: 'folder',
|
|
1328
1367
|
children: [],
|
|
1329
1368
|
parent: this.currentFolder,
|
|
1330
1369
|
metadata: {}
|
|
1331
1370
|
};
|
|
1332
|
-
|
|
1371
|
+
dir.push(newFolder);
|
|
1333
1372
|
this._refreshContent();
|
|
1334
1373
|
this.tree?.refresh();
|
|
1335
1374
|
if (this._moveItemDialog && this._movingItem) {
|