lexgui 0.7.13 → 0.7.15
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/extensions/codeeditor.js +396 -224
- package/build/lexgui.css +3 -2
- package/build/lexgui.js +440 -300
- package/build/lexgui.min.css +1 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +464 -324
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +30 -1
- package/examples/asset-view.html +15 -5
- package/package.json +1 -1
package/build/lexgui.js
CHANGED
|
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const LX = {
|
|
17
|
-
version: "0.7.
|
|
17
|
+
version: "0.7.15",
|
|
18
18
|
ready: false,
|
|
19
19
|
extensions: [], // Store extensions used
|
|
20
20
|
signals: {}, // Events and triggers
|
|
@@ -16370,8 +16370,9 @@ class AssetView {
|
|
|
16370
16370
|
this.onlyFolders = options.onlyFolders ?? true;
|
|
16371
16371
|
this.allowMultipleSelection = options.allowMultipleSelection ?? false;
|
|
16372
16372
|
this.previewActions = options.previewActions ?? [];
|
|
16373
|
-
this.
|
|
16373
|
+
this.itemContextMenuOptions = options.itemContextMenuOptions;
|
|
16374
16374
|
this.onRefreshContent = options.onRefreshContent;
|
|
16375
|
+
this.onItemDragged = options.onItemDragged;
|
|
16375
16376
|
|
|
16376
16377
|
// Append temporarily to the dom
|
|
16377
16378
|
document.body.appendChild( this.root );
|
|
@@ -16398,6 +16399,7 @@ class AssetView {
|
|
|
16398
16399
|
|
|
16399
16400
|
this._processData( this.data, null );
|
|
16400
16401
|
|
|
16402
|
+
this.currentFolder = null;
|
|
16401
16403
|
this.currentData = this.data;
|
|
16402
16404
|
this.path = ['@'];
|
|
16403
16405
|
|
|
@@ -16443,6 +16445,284 @@ class AssetView {
|
|
|
16443
16445
|
this.onevent = onevent;
|
|
16444
16446
|
}
|
|
16445
16447
|
|
|
16448
|
+
/**
|
|
16449
|
+
* @method addItem
|
|
16450
|
+
*/
|
|
16451
|
+
|
|
16452
|
+
addItem( item, childIndex, updateTree = true ) {
|
|
16453
|
+
|
|
16454
|
+
const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
|
|
16455
|
+
const isGridLayout = ( this.layout == AssetView.LAYOUT_GRID ); // default
|
|
16456
|
+
const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
|
|
16457
|
+
const extension = LX.getExtension( item.id );
|
|
16458
|
+
const isFolder = type === "Folder";
|
|
16459
|
+
const that = this;
|
|
16460
|
+
|
|
16461
|
+
let itemEl = document.createElement('li');
|
|
16462
|
+
itemEl.className = "lexassetitem " + item.type.toLowerCase();
|
|
16463
|
+
itemEl.tabIndex = -1;
|
|
16464
|
+
this.content.insertChildAtIndex( itemEl, childIndex );
|
|
16465
|
+
|
|
16466
|
+
if( item.lastModified && !item.lastModifiedDate )
|
|
16467
|
+
{
|
|
16468
|
+
item.lastModifiedDate = this._lastModifiedToStringDate( item.lastModified );
|
|
16469
|
+
}
|
|
16470
|
+
|
|
16471
|
+
if( !this.useNativeTitle )
|
|
16472
|
+
{
|
|
16473
|
+
let desc = document.createElement( 'span' );
|
|
16474
|
+
desc.className = 'lexitemdesc';
|
|
16475
|
+
desc.id = `floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }`;
|
|
16476
|
+
desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
|
|
16477
|
+
this.content.insertChildAtIndex( desc, childIndex ? childIndex + 1 : undefined );
|
|
16478
|
+
|
|
16479
|
+
itemEl.addEventListener( "mousemove", e => {
|
|
16480
|
+
|
|
16481
|
+
if( !isGridLayout )
|
|
16482
|
+
{
|
|
16483
|
+
return;
|
|
16484
|
+
}
|
|
16485
|
+
|
|
16486
|
+
const dialog = itemEl.closest('dialog');
|
|
16487
|
+
const rect = itemEl.getBoundingClientRect();
|
|
16488
|
+
const targetRect = e.target.getBoundingClientRect();
|
|
16489
|
+
|
|
16490
|
+
let localOffsetX = rect.x + e.offsetX;
|
|
16491
|
+
let localOffsetY = rect.y + e.offsetY;
|
|
16492
|
+
|
|
16493
|
+
if( dialog )
|
|
16494
|
+
{
|
|
16495
|
+
const dialogRect = dialog.getBoundingClientRect();
|
|
16496
|
+
localOffsetX -= dialogRect.x;
|
|
16497
|
+
localOffsetY -= dialogRect.y;
|
|
16498
|
+
}
|
|
16499
|
+
|
|
16500
|
+
if( e.target.classList.contains( "lexassettitle" ) )
|
|
16501
|
+
{
|
|
16502
|
+
localOffsetY += ( targetRect.y - rect.y );
|
|
16503
|
+
}
|
|
16504
|
+
|
|
16505
|
+
desc.style.left = ( localOffsetX ) + "px";
|
|
16506
|
+
desc.style.top = ( localOffsetY - 36 ) + "px";
|
|
16507
|
+
} );
|
|
16508
|
+
}
|
|
16509
|
+
else
|
|
16510
|
+
{
|
|
16511
|
+
itemEl.title = type + ": " + item.id;
|
|
16512
|
+
}
|
|
16513
|
+
|
|
16514
|
+
if( this.allowMultipleSelection )
|
|
16515
|
+
{
|
|
16516
|
+
let checkbox = document.createElement( 'input' );
|
|
16517
|
+
checkbox.type = "checkbox";
|
|
16518
|
+
checkbox.className = "lexcheckbox";
|
|
16519
|
+
checkbox.checked = item.selected;
|
|
16520
|
+
checkbox.addEventListener('change', ( e, v ) => {
|
|
16521
|
+
item.selected = !item.selected;
|
|
16522
|
+
if( this.onevent )
|
|
16523
|
+
{
|
|
16524
|
+
const event = new AssetViewEvent(AssetViewEvent.ASSET_CHECKED, e.shiftKey ? [item] : item );
|
|
16525
|
+
event.multiple = !!e.shiftKey;
|
|
16526
|
+
this.onevent( event );
|
|
16527
|
+
}
|
|
16528
|
+
e.stopPropagation();
|
|
16529
|
+
e.stopImmediatePropagation();
|
|
16530
|
+
});
|
|
16531
|
+
|
|
16532
|
+
itemEl.appendChild( checkbox );
|
|
16533
|
+
}
|
|
16534
|
+
|
|
16535
|
+
let title = document.createElement('span');
|
|
16536
|
+
title.className = "lexassettitle";
|
|
16537
|
+
title.innerText = item.id;
|
|
16538
|
+
itemEl.appendChild( title );
|
|
16539
|
+
|
|
16540
|
+
if( !this.skipPreview )
|
|
16541
|
+
{
|
|
16542
|
+
if( item.type === 'video' )
|
|
16543
|
+
{
|
|
16544
|
+
const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
|
|
16545
|
+
itemVideo.setAttribute( 'disablePictureInPicture', false );
|
|
16546
|
+
itemVideo.setAttribute( 'disableRemotePlayback', false );
|
|
16547
|
+
itemVideo.setAttribute( 'loop', true );
|
|
16548
|
+
itemVideo.setAttribute( 'async', true );
|
|
16549
|
+
itemVideo.style.transition = 'opacity 0.2s ease-out';
|
|
16550
|
+
itemVideo.style.opacity = item.preview ? '0' : '1';
|
|
16551
|
+
itemVideo.src = item.src;
|
|
16552
|
+
itemVideo.volume = item.videoVolume ?? 0.4;
|
|
16553
|
+
}
|
|
16554
|
+
|
|
16555
|
+
let preview = null;
|
|
16556
|
+
|
|
16557
|
+
const previewSrc = item.preview ?? item.src;
|
|
16558
|
+
const hasImage = previewSrc && (
|
|
16559
|
+
(() => {
|
|
16560
|
+
const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
|
|
16561
|
+
return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
|
|
16562
|
+
})()
|
|
16563
|
+
|| previewSrc.startsWith( 'data:image/' )
|
|
16564
|
+
);
|
|
16565
|
+
|
|
16566
|
+
if( hasImage || isFolder || !isGridLayout )
|
|
16567
|
+
{
|
|
16568
|
+
const defaultPreviewPath = `${ this.rootPath }images/file.png`;
|
|
16569
|
+
const defaultFolderPath = `${ this.rootPath }images/folder.png`;
|
|
16570
|
+
|
|
16571
|
+
preview = document.createElement('img');
|
|
16572
|
+
let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
|
|
16573
|
+
preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
|
|
16574
|
+
itemEl.appendChild( preview );
|
|
16575
|
+
}
|
|
16576
|
+
else
|
|
16577
|
+
{
|
|
16578
|
+
preview = document.createElement( 'svg' );
|
|
16579
|
+
preview.className = 'asset-file-preview';
|
|
16580
|
+
itemEl.appendChild( preview );
|
|
16581
|
+
|
|
16582
|
+
let textEl = document.createElement( 'text' );
|
|
16583
|
+
textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
|
|
16584
|
+
preview.appendChild( textEl );
|
|
16585
|
+
|
|
16586
|
+
var newLength = textEl.innerText.length;
|
|
16587
|
+
var charsPerLine = 2.5;
|
|
16588
|
+
var newEmSize = charsPerLine / newLength;
|
|
16589
|
+
var textBaseSize = 64;
|
|
16590
|
+
|
|
16591
|
+
if( newEmSize < 1 )
|
|
16592
|
+
{
|
|
16593
|
+
var newFontSize = newEmSize * textBaseSize;
|
|
16594
|
+
textEl.style.fontSize = newFontSize + 'px';
|
|
16595
|
+
preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
|
|
16596
|
+
}
|
|
16597
|
+
}
|
|
16598
|
+
}
|
|
16599
|
+
|
|
16600
|
+
// Add item type info
|
|
16601
|
+
let itemInfoHtml = type;
|
|
16602
|
+
|
|
16603
|
+
if( isListLayout )
|
|
16604
|
+
{
|
|
16605
|
+
if( item.bytesize ) itemInfoHtml += ` | ${ LX.formatBytes( item.bytesize ) }`;
|
|
16606
|
+
if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
|
|
16607
|
+
}
|
|
16608
|
+
|
|
16609
|
+
LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
|
|
16610
|
+
|
|
16611
|
+
itemEl.addEventListener('click', function( e ) {
|
|
16612
|
+
e.stopImmediatePropagation();
|
|
16613
|
+
e.stopPropagation();
|
|
16614
|
+
|
|
16615
|
+
const isDoubleClick = ( e.detail == LX.MOUSE_DOUBLE_CLICK );
|
|
16616
|
+
|
|
16617
|
+
if( !isDoubleClick )
|
|
16618
|
+
{
|
|
16619
|
+
if( !e.shiftKey )
|
|
16620
|
+
{
|
|
16621
|
+
that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
|
|
16622
|
+
}
|
|
16623
|
+
|
|
16624
|
+
this.classList.add( 'selected' );
|
|
16625
|
+
that.selectedItem = item;
|
|
16626
|
+
|
|
16627
|
+
if( !that.skipPreview )
|
|
16628
|
+
{
|
|
16629
|
+
that._previewAsset( item );
|
|
16630
|
+
}
|
|
16631
|
+
}
|
|
16632
|
+
else if( isFolder )
|
|
16633
|
+
{
|
|
16634
|
+
that._enterFolder( item );
|
|
16635
|
+
return;
|
|
16636
|
+
}
|
|
16637
|
+
|
|
16638
|
+
if( that.onevent )
|
|
16639
|
+
{
|
|
16640
|
+
const event = new AssetViewEvent(isDoubleClick ? AssetViewEvent.ASSET_DBLCLICKED : AssetViewEvent.ASSET_SELECTED, e.shiftKey ? [item] : item );
|
|
16641
|
+
event.multiple = !!e.shiftKey;
|
|
16642
|
+
that.onevent( event );
|
|
16643
|
+
}
|
|
16644
|
+
});
|
|
16645
|
+
|
|
16646
|
+
itemEl.addEventListener('contextmenu', function( e ) {
|
|
16647
|
+
e.preventDefault();
|
|
16648
|
+
|
|
16649
|
+
const multiple = that.content.querySelectorAll('.selected').length;
|
|
16650
|
+
|
|
16651
|
+
LX.addContextMenu( multiple > 1 ? ( multiple + " selected" ) : isFolder ? item.id : item.type, e, m =>
|
|
16652
|
+
{
|
|
16653
|
+
if( multiple <= 1 )
|
|
16654
|
+
{
|
|
16655
|
+
m.add("Rename", that._renameItem.bind( that, item ));
|
|
16656
|
+
}
|
|
16657
|
+
|
|
16658
|
+
if( !isFolder )
|
|
16659
|
+
{
|
|
16660
|
+
m.add("Clone", that._cloneItem.bind( that, item ));
|
|
16661
|
+
}
|
|
16662
|
+
|
|
16663
|
+
m.add("Delete", that._deleteItem.bind( that, item ));
|
|
16664
|
+
|
|
16665
|
+
if( that.itemContextMenuOptions )
|
|
16666
|
+
{
|
|
16667
|
+
m.add("");
|
|
16668
|
+
|
|
16669
|
+
for( let o of that.itemContextMenuOptions )
|
|
16670
|
+
{
|
|
16671
|
+
if( !o.name || !o.callback ) continue;
|
|
16672
|
+
m.add( o.name, o.callback?.bind( that, item ) );
|
|
16673
|
+
}
|
|
16674
|
+
}
|
|
16675
|
+
});
|
|
16676
|
+
});
|
|
16677
|
+
|
|
16678
|
+
itemEl.addEventListener("dragstart", function( e ) {
|
|
16679
|
+
e.preventDefault();
|
|
16680
|
+
}, false );
|
|
16681
|
+
|
|
16682
|
+
itemEl.addEventListener( "mouseenter", ( e ) => {
|
|
16683
|
+
|
|
16684
|
+
if( !that.useNativeTitle && isGridLayout )
|
|
16685
|
+
{
|
|
16686
|
+
const desc = that.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
|
|
16687
|
+
if( desc ) desc.style.display = "unset";
|
|
16688
|
+
}
|
|
16689
|
+
|
|
16690
|
+
if( item.type !== "video" ) return;
|
|
16691
|
+
e.preventDefault();
|
|
16692
|
+
const video = itemEl.querySelector( "video" );
|
|
16693
|
+
video.style.opacity = "1";
|
|
16694
|
+
video.play();
|
|
16695
|
+
} );
|
|
16696
|
+
|
|
16697
|
+
itemEl.addEventListener( "mouseleave", ( e ) => {
|
|
16698
|
+
|
|
16699
|
+
if( !that.useNativeTitle && isGridLayout )
|
|
16700
|
+
{
|
|
16701
|
+
setTimeout( () => {
|
|
16702
|
+
const desc = that.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
|
|
16703
|
+
if( desc ) desc.style.display = "none";
|
|
16704
|
+
}, 100 );
|
|
16705
|
+
}
|
|
16706
|
+
|
|
16707
|
+
if( item.type !== "video" ) return;
|
|
16708
|
+
e.preventDefault();
|
|
16709
|
+
const video = itemEl.querySelector( "video" );
|
|
16710
|
+
video.pause();
|
|
16711
|
+
video.currentTime = 0;
|
|
16712
|
+
if( item.preview )
|
|
16713
|
+
{
|
|
16714
|
+
video.style.opacity = "0";
|
|
16715
|
+
}
|
|
16716
|
+
} );
|
|
16717
|
+
|
|
16718
|
+
if( !this.skipBrowser && updateTree )
|
|
16719
|
+
{
|
|
16720
|
+
this.tree.refresh();
|
|
16721
|
+
}
|
|
16722
|
+
|
|
16723
|
+
return itemEl;
|
|
16724
|
+
}
|
|
16725
|
+
|
|
16446
16726
|
/**
|
|
16447
16727
|
* @method clear
|
|
16448
16728
|
*/
|
|
@@ -16488,21 +16768,26 @@ class AssetView {
|
|
|
16488
16768
|
* @method _updatePath
|
|
16489
16769
|
*/
|
|
16490
16770
|
|
|
16491
|
-
_updatePath(
|
|
16771
|
+
_updatePath() {
|
|
16492
16772
|
|
|
16493
16773
|
this.path.length = 0;
|
|
16494
16774
|
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
|
|
16775
|
+
if( this.currentFolder && this.currentFolder.parent )
|
|
16776
|
+
{
|
|
16777
|
+
this.path.push( this.currentFolder.id );
|
|
16778
|
+
|
|
16779
|
+
const push_parents_id = i => {
|
|
16780
|
+
if( !i ) return;
|
|
16781
|
+
this.path.push( i.parent ? i.id : '@' );
|
|
16782
|
+
push_parents_id( i.parent );
|
|
16783
|
+
};
|
|
16504
16784
|
|
|
16505
|
-
|
|
16785
|
+
push_parents_id( this.currentFolder.parent );
|
|
16786
|
+
}
|
|
16787
|
+
else
|
|
16788
|
+
{
|
|
16789
|
+
this.path.push( '@' );
|
|
16790
|
+
}
|
|
16506
16791
|
|
|
16507
16792
|
LX.emit( "@on_folder_change", this.path.reverse().join('/') );
|
|
16508
16793
|
}
|
|
@@ -16540,24 +16825,62 @@ class AssetView {
|
|
|
16540
16825
|
switch( event.type )
|
|
16541
16826
|
{
|
|
16542
16827
|
case LX.TreeEvent.NODE_SELECTED:
|
|
16543
|
-
|
|
16828
|
+
{
|
|
16829
|
+
if( event.multiple )
|
|
16544
16830
|
{
|
|
16545
|
-
|
|
16831
|
+
return;
|
|
16546
16832
|
}
|
|
16547
16833
|
if( !node.parent )
|
|
16548
16834
|
{
|
|
16549
|
-
|
|
16835
|
+
if( this.currentFolder )
|
|
16836
|
+
{
|
|
16837
|
+
this.prevData.push( this.currentFolder );
|
|
16838
|
+
}
|
|
16839
|
+
|
|
16840
|
+
this.currentFolder = null;
|
|
16550
16841
|
this.currentData = this.data;
|
|
16551
16842
|
this._refreshContent();
|
|
16843
|
+
this._updatePath();
|
|
16844
|
+
}
|
|
16845
|
+
else
|
|
16846
|
+
{
|
|
16847
|
+
this._enterFolder( node.type === "folder" ? node : node.parent );
|
|
16848
|
+
|
|
16849
|
+
this._previewAsset( node );
|
|
16552
16850
|
|
|
16553
|
-
|
|
16554
|
-
|
|
16851
|
+
if( node.type !== "folder" )
|
|
16852
|
+
{
|
|
16853
|
+
this.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
|
|
16854
|
+
const dom = node.domEl;
|
|
16855
|
+
dom?.classList.add( 'selected' );
|
|
16856
|
+
}
|
|
16857
|
+
|
|
16858
|
+
this.selectedItem = node;
|
|
16555
16859
|
}
|
|
16556
16860
|
break;
|
|
16861
|
+
}
|
|
16557
16862
|
case LX.TreeEvent.NODE_DRAGGED:
|
|
16558
|
-
|
|
16863
|
+
{
|
|
16864
|
+
if( node.parent )
|
|
16865
|
+
{
|
|
16866
|
+
const idx = node.parent.children.indexOf( node );
|
|
16867
|
+
node.parent.children.splice( idx, 1 );
|
|
16868
|
+
}
|
|
16869
|
+
|
|
16870
|
+
node.folder = node.parent = value;
|
|
16871
|
+
|
|
16872
|
+
if( !value.children ) value.children = [];
|
|
16873
|
+
|
|
16874
|
+
value.children.push( node );
|
|
16875
|
+
|
|
16876
|
+
if( this.onItemDragged )
|
|
16877
|
+
{
|
|
16878
|
+
this.onItemDragged( node, value );
|
|
16879
|
+
}
|
|
16880
|
+
|
|
16559
16881
|
this._refreshContent();
|
|
16560
16882
|
break;
|
|
16883
|
+
}
|
|
16561
16884
|
}
|
|
16562
16885
|
},
|
|
16563
16886
|
});
|
|
@@ -16654,22 +16977,17 @@ class AssetView {
|
|
|
16654
16977
|
value: "Left",
|
|
16655
16978
|
icon: "ArrowLeft",
|
|
16656
16979
|
callback: domEl => {
|
|
16657
|
-
if(!this.prevData.length) return;
|
|
16658
|
-
this.nextData.push( this.
|
|
16659
|
-
this.
|
|
16660
|
-
this._refreshContent();
|
|
16661
|
-
this._updatePath( this.currentData );
|
|
16980
|
+
if( !this.prevData.length || !this.currentFolder ) return;
|
|
16981
|
+
this.nextData.push( this.currentFolder );
|
|
16982
|
+
this._enterFolder( this.prevData.pop(), false );
|
|
16662
16983
|
}
|
|
16663
16984
|
},
|
|
16664
16985
|
{
|
|
16665
16986
|
value: "Right",
|
|
16666
16987
|
icon: "ArrowRight",
|
|
16667
16988
|
callback: domEl => {
|
|
16668
|
-
if(!this.nextData.length) return;
|
|
16669
|
-
this.
|
|
16670
|
-
this.currentData = this.nextData.pop();
|
|
16671
|
-
this._refreshContent();
|
|
16672
|
-
this._updatePath( this.currentData );
|
|
16989
|
+
if( !this.nextData.length || !this.currentFolder ) return;
|
|
16990
|
+
this._enterFolder( this.nextData.pop() );
|
|
16673
16991
|
}
|
|
16674
16992
|
},
|
|
16675
16993
|
{
|
|
@@ -16680,7 +16998,7 @@ class AssetView {
|
|
|
16680
16998
|
], { noSelection: true } );
|
|
16681
16999
|
|
|
16682
17000
|
this.toolsPanel.addText(null, this.path.join('/'), null, {
|
|
16683
|
-
inputClass: "nobg", disabled: true, signal: "@on_folder_change",
|
|
17001
|
+
width: "75%", inputClass: "nobg", disabled: true, signal: "@on_folder_change",
|
|
16684
17002
|
style: { fontWeight: "600", fontSize: "15px" }
|
|
16685
17003
|
});
|
|
16686
17004
|
|
|
@@ -16717,7 +17035,6 @@ class AssetView {
|
|
|
16717
17035
|
|
|
16718
17036
|
_refreshContent( searchValue, filter ) {
|
|
16719
17037
|
|
|
16720
|
-
const isGridLayout = ( this.layout == AssetView.LAYOUT_GRID ); // default
|
|
16721
17038
|
const isCompactLayout = ( this.layout == AssetView.LAYOUT_COMPACT );
|
|
16722
17039
|
const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
|
|
16723
17040
|
|
|
@@ -16725,268 +17042,6 @@ class AssetView {
|
|
|
16725
17042
|
this.searchValue = searchValue ?? ( this.searchValue ?? "" );
|
|
16726
17043
|
this.content.innerHTML = "";
|
|
16727
17044
|
this.content.className = `lexassetscontent${ isCompactLayout ? " compact" : ( isListLayout ? " list" : "" ) }`;
|
|
16728
|
-
let that = this;
|
|
16729
|
-
|
|
16730
|
-
const _addItem = function( item )
|
|
16731
|
-
{
|
|
16732
|
-
const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
|
|
16733
|
-
const extension = LX.getExtension( item.id );
|
|
16734
|
-
const isFolder = type === "Folder";
|
|
16735
|
-
|
|
16736
|
-
let itemEl = document.createElement('li');
|
|
16737
|
-
itemEl.className = "lexassetitem " + item.type.toLowerCase();
|
|
16738
|
-
itemEl.tabIndex = -1;
|
|
16739
|
-
that.content.appendChild( itemEl );
|
|
16740
|
-
|
|
16741
|
-
if( item.lastModified && !item.lastModifiedDate )
|
|
16742
|
-
{
|
|
16743
|
-
item.lastModifiedDate = that._lastModifiedToStringDate( item.lastModified );
|
|
16744
|
-
}
|
|
16745
|
-
|
|
16746
|
-
if( !that.useNativeTitle )
|
|
16747
|
-
{
|
|
16748
|
-
let desc = document.createElement( 'span' );
|
|
16749
|
-
desc.className = 'lexitemdesc';
|
|
16750
|
-
desc.id = `floatingTitle_${ item.id }`;
|
|
16751
|
-
desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
|
|
16752
|
-
that.content.appendChild( desc );
|
|
16753
|
-
|
|
16754
|
-
itemEl.addEventListener( "mousemove", e => {
|
|
16755
|
-
|
|
16756
|
-
if( !isGridLayout )
|
|
16757
|
-
{
|
|
16758
|
-
return;
|
|
16759
|
-
}
|
|
16760
|
-
|
|
16761
|
-
const dialog = itemEl.closest('dialog');
|
|
16762
|
-
const rect = itemEl.getBoundingClientRect();
|
|
16763
|
-
const targetRect = e.target.getBoundingClientRect();
|
|
16764
|
-
|
|
16765
|
-
let localOffsetX = rect.x + e.offsetX;
|
|
16766
|
-
let localOffsetY = rect.y + e.offsetY;
|
|
16767
|
-
|
|
16768
|
-
if( dialog )
|
|
16769
|
-
{
|
|
16770
|
-
const dialogRect = dialog.getBoundingClientRect();
|
|
16771
|
-
localOffsetX -= dialogRect.x;
|
|
16772
|
-
localOffsetY -= dialogRect.y;
|
|
16773
|
-
}
|
|
16774
|
-
|
|
16775
|
-
if( e.target.classList.contains( "lexassettitle" ) )
|
|
16776
|
-
{
|
|
16777
|
-
localOffsetY += ( targetRect.y - rect.y );
|
|
16778
|
-
}
|
|
16779
|
-
|
|
16780
|
-
desc.style.left = ( localOffsetX ) + "px";
|
|
16781
|
-
desc.style.top = ( localOffsetY - 36 ) + "px";
|
|
16782
|
-
} );
|
|
16783
|
-
}
|
|
16784
|
-
else
|
|
16785
|
-
{
|
|
16786
|
-
itemEl.title = type + ": " + item.id;
|
|
16787
|
-
}
|
|
16788
|
-
|
|
16789
|
-
if( that.allowMultipleSelection )
|
|
16790
|
-
{
|
|
16791
|
-
let checkbox = document.createElement( 'input' );
|
|
16792
|
-
checkbox.type = "checkbox";
|
|
16793
|
-
checkbox.className = "lexcheckbox";
|
|
16794
|
-
checkbox.checked = item.selected;
|
|
16795
|
-
checkbox.addEventListener('change', ( e, v ) => {
|
|
16796
|
-
item.selected = !item.selected;
|
|
16797
|
-
if( that.onevent )
|
|
16798
|
-
{
|
|
16799
|
-
const event = new AssetViewEvent(AssetViewEvent.ASSET_CHECKED, e.shiftKey ? [item] : item );
|
|
16800
|
-
event.multiple = !!e.shiftKey;
|
|
16801
|
-
that.onevent( event );
|
|
16802
|
-
}
|
|
16803
|
-
e.stopPropagation();
|
|
16804
|
-
e.stopImmediatePropagation();
|
|
16805
|
-
});
|
|
16806
|
-
|
|
16807
|
-
itemEl.appendChild( checkbox );
|
|
16808
|
-
}
|
|
16809
|
-
|
|
16810
|
-
let title = document.createElement('span');
|
|
16811
|
-
title.className = "lexassettitle";
|
|
16812
|
-
title.innerText = item.id;
|
|
16813
|
-
itemEl.appendChild( title );
|
|
16814
|
-
|
|
16815
|
-
if( !that.skipPreview )
|
|
16816
|
-
{
|
|
16817
|
-
if( item.type === 'video' )
|
|
16818
|
-
{
|
|
16819
|
-
const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
|
|
16820
|
-
itemVideo.setAttribute( 'disablePictureInPicture', false );
|
|
16821
|
-
itemVideo.setAttribute( 'disableRemotePlayback', false );
|
|
16822
|
-
itemVideo.setAttribute( 'loop', true );
|
|
16823
|
-
itemVideo.setAttribute( 'async', true );
|
|
16824
|
-
itemVideo.style.transition = 'opacity 0.2s ease-out';
|
|
16825
|
-
itemVideo.style.opacity = item.preview ? '0' : '1';
|
|
16826
|
-
itemVideo.src = item.src;
|
|
16827
|
-
itemVideo.volume = item.videoVolume ?? 0.4;
|
|
16828
|
-
}
|
|
16829
|
-
|
|
16830
|
-
let preview = null;
|
|
16831
|
-
|
|
16832
|
-
const previewSrc = item.preview ?? item.src;
|
|
16833
|
-
const hasImage = previewSrc && (
|
|
16834
|
-
(() => {
|
|
16835
|
-
const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
|
|
16836
|
-
return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
|
|
16837
|
-
})()
|
|
16838
|
-
|| previewSrc.startsWith( 'data:image/' )
|
|
16839
|
-
);
|
|
16840
|
-
|
|
16841
|
-
if( hasImage || isFolder || !isGridLayout )
|
|
16842
|
-
{
|
|
16843
|
-
const defaultPreviewPath = `${ that.rootPath }images/file.png`;
|
|
16844
|
-
const defaultFolderPath = `${ that.rootPath }images/folder.png`;
|
|
16845
|
-
|
|
16846
|
-
preview = document.createElement('img');
|
|
16847
|
-
let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
|
|
16848
|
-
preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
|
|
16849
|
-
itemEl.appendChild( preview );
|
|
16850
|
-
}
|
|
16851
|
-
else
|
|
16852
|
-
{
|
|
16853
|
-
preview = document.createElement( 'svg' );
|
|
16854
|
-
preview.className = 'asset-file-preview';
|
|
16855
|
-
itemEl.appendChild( preview );
|
|
16856
|
-
|
|
16857
|
-
let textEl = document.createElement( 'text' );
|
|
16858
|
-
textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `.${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
|
|
16859
|
-
preview.appendChild( textEl );
|
|
16860
|
-
|
|
16861
|
-
var newLength = textEl.innerText.length;
|
|
16862
|
-
var charsPerLine = 2.5;
|
|
16863
|
-
var newEmSize = charsPerLine / newLength;
|
|
16864
|
-
var textBaseSize = 64;
|
|
16865
|
-
|
|
16866
|
-
if( newEmSize < 1 )
|
|
16867
|
-
{
|
|
16868
|
-
var newFontSize = newEmSize * textBaseSize;
|
|
16869
|
-
textEl.style.fontSize = newFontSize + 'px';
|
|
16870
|
-
preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
|
|
16871
|
-
}
|
|
16872
|
-
}
|
|
16873
|
-
}
|
|
16874
|
-
|
|
16875
|
-
// Add item type info
|
|
16876
|
-
let itemInfoHtml = type;
|
|
16877
|
-
|
|
16878
|
-
if( isListLayout )
|
|
16879
|
-
{
|
|
16880
|
-
if( item.bytesize ) itemInfoHtml += ` | ${ LX.formatBytes( item.bytesize ) }`;
|
|
16881
|
-
if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
|
|
16882
|
-
}
|
|
16883
|
-
|
|
16884
|
-
LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
|
|
16885
|
-
|
|
16886
|
-
itemEl.addEventListener('click', function( e ) {
|
|
16887
|
-
e.stopImmediatePropagation();
|
|
16888
|
-
e.stopPropagation();
|
|
16889
|
-
|
|
16890
|
-
const isDoubleClick = ( e.detail == LX.MOUSE_DOUBLE_CLICK );
|
|
16891
|
-
|
|
16892
|
-
if( !isDoubleClick )
|
|
16893
|
-
{
|
|
16894
|
-
if( !e.shiftKey )
|
|
16895
|
-
{
|
|
16896
|
-
that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
|
|
16897
|
-
}
|
|
16898
|
-
|
|
16899
|
-
this.classList.add( 'selected' );
|
|
16900
|
-
that.selectedItem = item;
|
|
16901
|
-
|
|
16902
|
-
if( !that.skipPreview )
|
|
16903
|
-
{
|
|
16904
|
-
that._previewAsset( item );
|
|
16905
|
-
}
|
|
16906
|
-
}
|
|
16907
|
-
else if( isFolder )
|
|
16908
|
-
{
|
|
16909
|
-
that._enterFolder( item );
|
|
16910
|
-
return;
|
|
16911
|
-
}
|
|
16912
|
-
|
|
16913
|
-
if( that.onevent )
|
|
16914
|
-
{
|
|
16915
|
-
const event = new AssetViewEvent(isDoubleClick ? AssetViewEvent.ASSET_DBLCLICKED : AssetViewEvent.ASSET_SELECTED, e.shiftKey ? [item] : item );
|
|
16916
|
-
event.multiple = !!e.shiftKey;
|
|
16917
|
-
that.onevent( event );
|
|
16918
|
-
}
|
|
16919
|
-
});
|
|
16920
|
-
|
|
16921
|
-
if( that.contextMenu )
|
|
16922
|
-
{
|
|
16923
|
-
itemEl.addEventListener('contextmenu', function( e ) {
|
|
16924
|
-
e.preventDefault();
|
|
16925
|
-
|
|
16926
|
-
const multiple = that.content.querySelectorAll('.selected').length;
|
|
16927
|
-
|
|
16928
|
-
LX.addContextMenu( multiple > 1 ? (multiple + " selected") :
|
|
16929
|
-
isFolder ? item.id : item.type, e, m => {
|
|
16930
|
-
if( multiple <= 1 )
|
|
16931
|
-
{
|
|
16932
|
-
m.add("Rename");
|
|
16933
|
-
}
|
|
16934
|
-
if( !isFolder )
|
|
16935
|
-
{
|
|
16936
|
-
m.add("Clone", that._cloneItem.bind( that, item ));
|
|
16937
|
-
}
|
|
16938
|
-
if( multiple <= 1 )
|
|
16939
|
-
{
|
|
16940
|
-
m.add("Properties");
|
|
16941
|
-
}
|
|
16942
|
-
m.add("");
|
|
16943
|
-
m.add("Delete", that._deleteItem.bind( that, item ));
|
|
16944
|
-
});
|
|
16945
|
-
});
|
|
16946
|
-
}
|
|
16947
|
-
|
|
16948
|
-
itemEl.addEventListener("dragstart", function( e ) {
|
|
16949
|
-
e.preventDefault();
|
|
16950
|
-
}, false );
|
|
16951
|
-
|
|
16952
|
-
itemEl.addEventListener( "mouseenter", ( e ) => {
|
|
16953
|
-
|
|
16954
|
-
if( !that.useNativeTitle && isGridLayout )
|
|
16955
|
-
{
|
|
16956
|
-
const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
|
|
16957
|
-
if( desc ) desc.style.display = "unset";
|
|
16958
|
-
}
|
|
16959
|
-
|
|
16960
|
-
if( item.type !== "video" ) return;
|
|
16961
|
-
e.preventDefault();
|
|
16962
|
-
const video = itemEl.querySelector( "video" );
|
|
16963
|
-
video.style.opacity = "1";
|
|
16964
|
-
video.play();
|
|
16965
|
-
} );
|
|
16966
|
-
|
|
16967
|
-
itemEl.addEventListener( "mouseleave", ( e ) => {
|
|
16968
|
-
|
|
16969
|
-
if( !that.useNativeTitle && isGridLayout )
|
|
16970
|
-
{
|
|
16971
|
-
setTimeout( () => {
|
|
16972
|
-
const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
|
|
16973
|
-
if( desc ) desc.style.display = "none";
|
|
16974
|
-
}, 100 );
|
|
16975
|
-
}
|
|
16976
|
-
|
|
16977
|
-
if( item.type !== "video" ) return;
|
|
16978
|
-
e.preventDefault();
|
|
16979
|
-
const video = itemEl.querySelector( "video" );
|
|
16980
|
-
video.pause();
|
|
16981
|
-
video.currentTime = 0;
|
|
16982
|
-
if( item.preview )
|
|
16983
|
-
{
|
|
16984
|
-
video.style.opacity = "0";
|
|
16985
|
-
}
|
|
16986
|
-
} );
|
|
16987
|
-
|
|
16988
|
-
return itemEl;
|
|
16989
|
-
};
|
|
16990
17045
|
|
|
16991
17046
|
const fr = new FileReader();
|
|
16992
17047
|
|
|
@@ -17022,7 +17077,7 @@ class AssetView {
|
|
|
17022
17077
|
} });
|
|
17023
17078
|
}else
|
|
17024
17079
|
{
|
|
17025
|
-
item.domEl =
|
|
17080
|
+
item.domEl = this.addItem( item, null, false );
|
|
17026
17081
|
}
|
|
17027
17082
|
}
|
|
17028
17083
|
|
|
@@ -17043,6 +17098,11 @@ class AssetView {
|
|
|
17043
17098
|
|
|
17044
17099
|
_previewAsset( file ) {
|
|
17045
17100
|
|
|
17101
|
+
if( this.skipPreview )
|
|
17102
|
+
{
|
|
17103
|
+
return;
|
|
17104
|
+
}
|
|
17105
|
+
|
|
17046
17106
|
const is_base_64 = file.src && file.src.includes("data:image/");
|
|
17047
17107
|
|
|
17048
17108
|
this.previewPanel.clear();
|
|
@@ -17057,6 +17117,11 @@ class AssetView {
|
|
|
17057
17117
|
}
|
|
17058
17118
|
}
|
|
17059
17119
|
|
|
17120
|
+
if( file.lastModified && !file.lastModifiedDate )
|
|
17121
|
+
{
|
|
17122
|
+
file.lastModifiedDate = this._lastModifiedToStringDate( file.lastModified );
|
|
17123
|
+
}
|
|
17124
|
+
|
|
17060
17125
|
const options = { disabled: true };
|
|
17061
17126
|
|
|
17062
17127
|
this.previewPanel.addText("Filename", file.id, null, options);
|
|
@@ -17162,15 +17227,27 @@ class AssetView {
|
|
|
17162
17227
|
this._refreshContent();
|
|
17163
17228
|
}
|
|
17164
17229
|
|
|
17165
|
-
_enterFolder( folderItem ) {
|
|
17230
|
+
_enterFolder( folderItem, storeCurrent = true ) {
|
|
17231
|
+
|
|
17232
|
+
const child = this.currentData[ 0 ];
|
|
17233
|
+
const sameFolder = child?.parent?.id === folderItem.id;
|
|
17234
|
+
|
|
17235
|
+
if( storeCurrent )
|
|
17236
|
+
{
|
|
17237
|
+
this.prevData.push( this.currentFolder ?? { id: "/", children: this.data } );
|
|
17238
|
+
}
|
|
17166
17239
|
|
|
17167
|
-
this.
|
|
17168
|
-
this.currentData =
|
|
17240
|
+
this.currentFolder = folderItem;
|
|
17241
|
+
this.currentData = this.currentFolder.children;
|
|
17169
17242
|
this.contentPage = 1;
|
|
17170
|
-
|
|
17243
|
+
|
|
17244
|
+
if( !sameFolder )
|
|
17245
|
+
{
|
|
17246
|
+
this._refreshContent();
|
|
17247
|
+
}
|
|
17171
17248
|
|
|
17172
17249
|
// Update path
|
|
17173
|
-
this._updatePath(
|
|
17250
|
+
this._updatePath();
|
|
17174
17251
|
|
|
17175
17252
|
// Trigger event
|
|
17176
17253
|
if( this.onevent )
|
|
@@ -17198,7 +17275,16 @@ class AssetView {
|
|
|
17198
17275
|
this.onevent( event );
|
|
17199
17276
|
}
|
|
17200
17277
|
|
|
17201
|
-
this.
|
|
17278
|
+
if( !this.skipBrowser )
|
|
17279
|
+
{
|
|
17280
|
+
this.tree.refresh();
|
|
17281
|
+
}
|
|
17282
|
+
|
|
17283
|
+
if( this.previewPanel )
|
|
17284
|
+
{
|
|
17285
|
+
this.previewPanel.clear();
|
|
17286
|
+
}
|
|
17287
|
+
|
|
17202
17288
|
this._processData( this.data );
|
|
17203
17289
|
}
|
|
17204
17290
|
|
|
@@ -17226,6 +17312,60 @@ class AssetView {
|
|
|
17226
17312
|
this._processData( this.data );
|
|
17227
17313
|
}
|
|
17228
17314
|
|
|
17315
|
+
_renameItem( item ) {
|
|
17316
|
+
|
|
17317
|
+
const idx = this.currentData.indexOf( item );
|
|
17318
|
+
if( idx < 0 )
|
|
17319
|
+
{
|
|
17320
|
+
return;
|
|
17321
|
+
}
|
|
17322
|
+
|
|
17323
|
+
const oldName = item.id;
|
|
17324
|
+
const wasSelected = item.domEl.hasClass( "selected" );
|
|
17325
|
+
|
|
17326
|
+
const onRename = ( value ) =>
|
|
17327
|
+
{
|
|
17328
|
+
p.destroy();
|
|
17329
|
+
|
|
17330
|
+
const hoverTitle = this.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
|
|
17331
|
+
hoverTitle.remove();
|
|
17332
|
+
item.domEl.remove();
|
|
17333
|
+
|
|
17334
|
+
item.id = value;
|
|
17335
|
+
item.domEl = this.addItem( item, idx * 2 );
|
|
17336
|
+
|
|
17337
|
+
if( this.onevent )
|
|
17338
|
+
{
|
|
17339
|
+
const event = new AssetViewEvent( AssetViewEvent.ASSET_RENAMED, item, oldName );
|
|
17340
|
+
this.onevent( event );
|
|
17341
|
+
}
|
|
17342
|
+
|
|
17343
|
+
if( wasSelected )
|
|
17344
|
+
{
|
|
17345
|
+
this._previewAsset( item );
|
|
17346
|
+
}
|
|
17347
|
+
|
|
17348
|
+
if( !this.skipBrowser )
|
|
17349
|
+
{
|
|
17350
|
+
this.tree.refresh();
|
|
17351
|
+
}
|
|
17352
|
+
|
|
17353
|
+
this._processData( this.data );
|
|
17354
|
+
};
|
|
17355
|
+
|
|
17356
|
+
let newName = item.id;
|
|
17357
|
+
const panel = new LX.Panel();
|
|
17358
|
+
panel.addText( null, item.id, ( v, e ) => {
|
|
17359
|
+
newName = v;
|
|
17360
|
+
if( e.constructor === KeyboardEvent ) onRename( v );
|
|
17361
|
+
});
|
|
17362
|
+
panel.addButton( null, "Save", ( v ) => {
|
|
17363
|
+
onRename( newName );
|
|
17364
|
+
}, { buttonClass: "contrast" });
|
|
17365
|
+
|
|
17366
|
+
const p = new LX.Popover( item.domEl, [ panel ], { align: "center", side: "bottom", sideOffset: -128 });
|
|
17367
|
+
}
|
|
17368
|
+
|
|
17229
17369
|
_lastModifiedToStringDate( lm ) {
|
|
17230
17370
|
const d = new Date( lm ).toLocaleString();
|
|
17231
17371
|
return d.substring( 0, d.indexOf( ',' ) );
|