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/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.13",
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.contextMenu = options.contextMenu ?? [];
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( data ) {
16771
+ _updatePath() {
16492
16772
 
16493
16773
  this.path.length = 0;
16494
16774
 
16495
- const push_parents_id = i => {
16496
- if( !i ) return;
16497
- let list = i.children ? i.children : i;
16498
- let c = list[ 0 ];
16499
- if( !c ) return;
16500
- if( !c.folder ) return;
16501
- this.path.push( c.folder.id ?? '@' );
16502
- push_parents_id( c.folder.folder );
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
- push_parents_id( data );
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
- if( !event.multiple )
16828
+ {
16829
+ if( event.multiple )
16544
16830
  {
16545
- this._enterFolder( node );
16831
+ return;
16546
16832
  }
16547
16833
  if( !node.parent )
16548
16834
  {
16549
- this.prevData.push( this.currentData );
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
- this.path = ['@'];
16554
- LX.emit("@on_folder_change", this.path.join('/'));
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
- node.folder = value;
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.currentData );
16659
- this.currentData = this.prevData.pop();
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.prevData.push( this.currentData );
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 = _addItem( item );
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.prevData.push( this.currentData );
17168
- this.currentData = folderItem.children;
17240
+ this.currentFolder = folderItem;
17241
+ this.currentData = this.currentFolder.children;
17169
17242
  this.contentPage = 1;
17170
- this._refreshContent();
17243
+
17244
+ if( !sameFolder )
17245
+ {
17246
+ this._refreshContent();
17247
+ }
17171
17248
 
17172
17249
  // Update path
17173
- this._updatePath(this.currentData);
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.tree.refresh();
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( ',' ) );