lexgui 0.7.14 → 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.
@@ -1,4 +1,4 @@
1
- // This is a generated file. Do not edit.
1
+ // This is a generated file. Do not edit.
2
2
  // Lexgui.js @jxarco
3
3
 
4
4
  /**
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  const LX = {
10
- version: "0.7.14",
10
+ version: "0.7.15",
11
11
  ready: false,
12
12
  extensions: [], // Store extensions used
13
13
  signals: {}, // Events and triggers
@@ -4570,8 +4570,8 @@ Element.prototype.ignore = function( eventName, callbackName ) {
4570
4570
  callbackName = callbackName ?? ( "_on" + eventName );
4571
4571
  const callback = this[ callbackName ];
4572
4572
  this.removeEventListener( eventName, callback );
4573
- };
4574
-
4573
+ };
4574
+
4575
4575
  // icons.js @jxarco
4576
4576
 
4577
4577
  const RAW_ICONS = {
@@ -4752,8 +4752,8 @@ LX.LucideIconAlias = {
4752
4752
  "RotateRight": "RotateCw",
4753
4753
  "RotateBack": "RotateCcw",
4754
4754
  "RotateLeft": "RotateCcw",
4755
- };
4756
-
4755
+ };
4756
+
4757
4757
  // utils.js @jxarco
4758
4758
 
4759
4759
  function clamp( num, min, max ) { return Math.min( Math.max( num, min ), max ); }
@@ -6776,8 +6776,8 @@ function drawSpline( ctx, pts, t )
6776
6776
  ctx.restore();
6777
6777
  }
6778
6778
 
6779
- LX.drawSpline = drawSpline;
6780
-
6779
+ LX.drawSpline = drawSpline;
6780
+
6781
6781
  // area.js @jxarco
6782
6782
 
6783
6783
  class AreaOverlayButtons {
@@ -7927,8 +7927,8 @@ class Area {
7927
7927
  }
7928
7928
  }
7929
7929
  }
7930
- LX.Area = Area;
7931
-
7930
+ LX.Area = Area;
7931
+
7932
7932
  // base_component.js @jxarco
7933
7933
 
7934
7934
  /**
@@ -13789,8 +13789,8 @@ class Rate extends BaseComponent
13789
13789
  }
13790
13790
  }
13791
13791
 
13792
- LX.Rate = Rate;
13793
-
13792
+ LX.Rate = Rate;
13793
+
13794
13794
  // panel.js @jxarco
13795
13795
 
13796
13796
  /**
@@ -14989,8 +14989,8 @@ class Panel {
14989
14989
  }
14990
14990
  }
14991
14991
 
14992
- LX.Panel = Panel;
14993
-
14992
+ LX.Panel = Panel;
14993
+
14994
14994
  // branch.js @jxarco
14995
14995
 
14996
14996
  /**
@@ -15214,8 +15214,8 @@ class Branch {
15214
15214
  }
15215
15215
  }
15216
15216
  }
15217
- LX.Branch = Branch;
15218
-
15217
+ LX.Branch = Branch;
15218
+
15219
15219
  // menubar.js @jxarco
15220
15220
 
15221
15221
  /**
@@ -15547,8 +15547,8 @@ class Menubar {
15547
15547
  }
15548
15548
  }
15549
15549
  }
15550
- LX.Menubar = Menubar;
15551
-
15550
+ LX.Menubar = Menubar;
15551
+
15552
15552
  // sidebar.js @jxarco
15553
15553
 
15554
15554
  /**
@@ -16272,8 +16272,8 @@ class Sidebar {
16272
16272
  }
16273
16273
  }
16274
16274
  }
16275
- LX.Sidebar = Sidebar;
16276
-
16275
+ LX.Sidebar = Sidebar;
16276
+
16277
16277
  // asset_view.js @jxarco
16278
16278
 
16279
16279
  class AssetViewEvent {
@@ -16363,8 +16363,9 @@ class AssetView {
16363
16363
  this.onlyFolders = options.onlyFolders ?? true;
16364
16364
  this.allowMultipleSelection = options.allowMultipleSelection ?? false;
16365
16365
  this.previewActions = options.previewActions ?? [];
16366
- this.contextMenu = options.contextMenu ?? [];
16366
+ this.itemContextMenuOptions = options.itemContextMenuOptions;
16367
16367
  this.onRefreshContent = options.onRefreshContent;
16368
+ this.onItemDragged = options.onItemDragged;
16368
16369
 
16369
16370
  // Append temporarily to the dom
16370
16371
  document.body.appendChild( this.root );
@@ -16391,6 +16392,7 @@ class AssetView {
16391
16392
 
16392
16393
  this._processData( this.data, null );
16393
16394
 
16395
+ this.currentFolder = null;
16394
16396
  this.currentData = this.data;
16395
16397
  this.path = ['@'];
16396
16398
 
@@ -16436,6 +16438,284 @@ class AssetView {
16436
16438
  this.onevent = onevent;
16437
16439
  }
16438
16440
 
16441
+ /**
16442
+ * @method addItem
16443
+ */
16444
+
16445
+ addItem( item, childIndex, updateTree = true ) {
16446
+
16447
+ const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
16448
+ const isGridLayout = ( this.layout == AssetView.LAYOUT_GRID ); // default
16449
+ const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
16450
+ const extension = LX.getExtension( item.id );
16451
+ const isFolder = type === "Folder";
16452
+ const that = this;
16453
+
16454
+ let itemEl = document.createElement('li');
16455
+ itemEl.className = "lexassetitem " + item.type.toLowerCase();
16456
+ itemEl.tabIndex = -1;
16457
+ this.content.insertChildAtIndex( itemEl, childIndex );
16458
+
16459
+ if( item.lastModified && !item.lastModifiedDate )
16460
+ {
16461
+ item.lastModifiedDate = this._lastModifiedToStringDate( item.lastModified );
16462
+ }
16463
+
16464
+ if( !this.useNativeTitle )
16465
+ {
16466
+ let desc = document.createElement( 'span' );
16467
+ desc.className = 'lexitemdesc';
16468
+ desc.id = `floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }`;
16469
+ desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
16470
+ this.content.insertChildAtIndex( desc, childIndex ? childIndex + 1 : undefined );
16471
+
16472
+ itemEl.addEventListener( "mousemove", e => {
16473
+
16474
+ if( !isGridLayout )
16475
+ {
16476
+ return;
16477
+ }
16478
+
16479
+ const dialog = itemEl.closest('dialog');
16480
+ const rect = itemEl.getBoundingClientRect();
16481
+ const targetRect = e.target.getBoundingClientRect();
16482
+
16483
+ let localOffsetX = rect.x + e.offsetX;
16484
+ let localOffsetY = rect.y + e.offsetY;
16485
+
16486
+ if( dialog )
16487
+ {
16488
+ const dialogRect = dialog.getBoundingClientRect();
16489
+ localOffsetX -= dialogRect.x;
16490
+ localOffsetY -= dialogRect.y;
16491
+ }
16492
+
16493
+ if( e.target.classList.contains( "lexassettitle" ) )
16494
+ {
16495
+ localOffsetY += ( targetRect.y - rect.y );
16496
+ }
16497
+
16498
+ desc.style.left = ( localOffsetX ) + "px";
16499
+ desc.style.top = ( localOffsetY - 36 ) + "px";
16500
+ } );
16501
+ }
16502
+ else
16503
+ {
16504
+ itemEl.title = type + ": " + item.id;
16505
+ }
16506
+
16507
+ if( this.allowMultipleSelection )
16508
+ {
16509
+ let checkbox = document.createElement( 'input' );
16510
+ checkbox.type = "checkbox";
16511
+ checkbox.className = "lexcheckbox";
16512
+ checkbox.checked = item.selected;
16513
+ checkbox.addEventListener('change', ( e, v ) => {
16514
+ item.selected = !item.selected;
16515
+ if( this.onevent )
16516
+ {
16517
+ const event = new AssetViewEvent(AssetViewEvent.ASSET_CHECKED, e.shiftKey ? [item] : item );
16518
+ event.multiple = !!e.shiftKey;
16519
+ this.onevent( event );
16520
+ }
16521
+ e.stopPropagation();
16522
+ e.stopImmediatePropagation();
16523
+ });
16524
+
16525
+ itemEl.appendChild( checkbox );
16526
+ }
16527
+
16528
+ let title = document.createElement('span');
16529
+ title.className = "lexassettitle";
16530
+ title.innerText = item.id;
16531
+ itemEl.appendChild( title );
16532
+
16533
+ if( !this.skipPreview )
16534
+ {
16535
+ if( item.type === 'video' )
16536
+ {
16537
+ const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
16538
+ itemVideo.setAttribute( 'disablePictureInPicture', false );
16539
+ itemVideo.setAttribute( 'disableRemotePlayback', false );
16540
+ itemVideo.setAttribute( 'loop', true );
16541
+ itemVideo.setAttribute( 'async', true );
16542
+ itemVideo.style.transition = 'opacity 0.2s ease-out';
16543
+ itemVideo.style.opacity = item.preview ? '0' : '1';
16544
+ itemVideo.src = item.src;
16545
+ itemVideo.volume = item.videoVolume ?? 0.4;
16546
+ }
16547
+
16548
+ let preview = null;
16549
+
16550
+ const previewSrc = item.preview ?? item.src;
16551
+ const hasImage = previewSrc && (
16552
+ (() => {
16553
+ const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
16554
+ return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
16555
+ })()
16556
+ || previewSrc.startsWith( 'data:image/' )
16557
+ );
16558
+
16559
+ if( hasImage || isFolder || !isGridLayout )
16560
+ {
16561
+ const defaultPreviewPath = `${ this.rootPath }images/file.png`;
16562
+ const defaultFolderPath = `${ this.rootPath }images/folder.png`;
16563
+
16564
+ preview = document.createElement('img');
16565
+ let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
16566
+ preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
16567
+ itemEl.appendChild( preview );
16568
+ }
16569
+ else
16570
+ {
16571
+ preview = document.createElement( 'svg' );
16572
+ preview.className = 'asset-file-preview';
16573
+ itemEl.appendChild( preview );
16574
+
16575
+ let textEl = document.createElement( 'text' );
16576
+ textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
16577
+ preview.appendChild( textEl );
16578
+
16579
+ var newLength = textEl.innerText.length;
16580
+ var charsPerLine = 2.5;
16581
+ var newEmSize = charsPerLine / newLength;
16582
+ var textBaseSize = 64;
16583
+
16584
+ if( newEmSize < 1 )
16585
+ {
16586
+ var newFontSize = newEmSize * textBaseSize;
16587
+ textEl.style.fontSize = newFontSize + 'px';
16588
+ preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
16589
+ }
16590
+ }
16591
+ }
16592
+
16593
+ // Add item type info
16594
+ let itemInfoHtml = type;
16595
+
16596
+ if( isListLayout )
16597
+ {
16598
+ if( item.bytesize ) itemInfoHtml += ` | ${ LX.formatBytes( item.bytesize ) }`;
16599
+ if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
16600
+ }
16601
+
16602
+ LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
16603
+
16604
+ itemEl.addEventListener('click', function( e ) {
16605
+ e.stopImmediatePropagation();
16606
+ e.stopPropagation();
16607
+
16608
+ const isDoubleClick = ( e.detail == LX.MOUSE_DOUBLE_CLICK );
16609
+
16610
+ if( !isDoubleClick )
16611
+ {
16612
+ if( !e.shiftKey )
16613
+ {
16614
+ that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16615
+ }
16616
+
16617
+ this.classList.add( 'selected' );
16618
+ that.selectedItem = item;
16619
+
16620
+ if( !that.skipPreview )
16621
+ {
16622
+ that._previewAsset( item );
16623
+ }
16624
+ }
16625
+ else if( isFolder )
16626
+ {
16627
+ that._enterFolder( item );
16628
+ return;
16629
+ }
16630
+
16631
+ if( that.onevent )
16632
+ {
16633
+ const event = new AssetViewEvent(isDoubleClick ? AssetViewEvent.ASSET_DBLCLICKED : AssetViewEvent.ASSET_SELECTED, e.shiftKey ? [item] : item );
16634
+ event.multiple = !!e.shiftKey;
16635
+ that.onevent( event );
16636
+ }
16637
+ });
16638
+
16639
+ itemEl.addEventListener('contextmenu', function( e ) {
16640
+ e.preventDefault();
16641
+
16642
+ const multiple = that.content.querySelectorAll('.selected').length;
16643
+
16644
+ LX.addContextMenu( multiple > 1 ? ( multiple + " selected" ) : isFolder ? item.id : item.type, e, m =>
16645
+ {
16646
+ if( multiple <= 1 )
16647
+ {
16648
+ m.add("Rename", that._renameItem.bind( that, item ));
16649
+ }
16650
+
16651
+ if( !isFolder )
16652
+ {
16653
+ m.add("Clone", that._cloneItem.bind( that, item ));
16654
+ }
16655
+
16656
+ m.add("Delete", that._deleteItem.bind( that, item ));
16657
+
16658
+ if( that.itemContextMenuOptions )
16659
+ {
16660
+ m.add("");
16661
+
16662
+ for( let o of that.itemContextMenuOptions )
16663
+ {
16664
+ if( !o.name || !o.callback ) continue;
16665
+ m.add( o.name, o.callback?.bind( that, item ) );
16666
+ }
16667
+ }
16668
+ });
16669
+ });
16670
+
16671
+ itemEl.addEventListener("dragstart", function( e ) {
16672
+ e.preventDefault();
16673
+ }, false );
16674
+
16675
+ itemEl.addEventListener( "mouseenter", ( e ) => {
16676
+
16677
+ if( !that.useNativeTitle && isGridLayout )
16678
+ {
16679
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
16680
+ if( desc ) desc.style.display = "unset";
16681
+ }
16682
+
16683
+ if( item.type !== "video" ) return;
16684
+ e.preventDefault();
16685
+ const video = itemEl.querySelector( "video" );
16686
+ video.style.opacity = "1";
16687
+ video.play();
16688
+ } );
16689
+
16690
+ itemEl.addEventListener( "mouseleave", ( e ) => {
16691
+
16692
+ if( !that.useNativeTitle && isGridLayout )
16693
+ {
16694
+ setTimeout( () => {
16695
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
16696
+ if( desc ) desc.style.display = "none";
16697
+ }, 100 );
16698
+ }
16699
+
16700
+ if( item.type !== "video" ) return;
16701
+ e.preventDefault();
16702
+ const video = itemEl.querySelector( "video" );
16703
+ video.pause();
16704
+ video.currentTime = 0;
16705
+ if( item.preview )
16706
+ {
16707
+ video.style.opacity = "0";
16708
+ }
16709
+ } );
16710
+
16711
+ if( !this.skipBrowser && updateTree )
16712
+ {
16713
+ this.tree.refresh();
16714
+ }
16715
+
16716
+ return itemEl;
16717
+ }
16718
+
16439
16719
  /**
16440
16720
  * @method clear
16441
16721
  */
@@ -16481,21 +16761,26 @@ class AssetView {
16481
16761
  * @method _updatePath
16482
16762
  */
16483
16763
 
16484
- _updatePath( data ) {
16764
+ _updatePath() {
16485
16765
 
16486
16766
  this.path.length = 0;
16487
16767
 
16488
- const push_parents_id = i => {
16489
- if( !i ) return;
16490
- let list = i.children ? i.children : i;
16491
- let c = list[ 0 ];
16492
- if( !c ) return;
16493
- if( !c.folder ) return;
16494
- this.path.push( c.folder.id ?? '@' );
16495
- push_parents_id( c.folder.folder );
16496
- };
16768
+ if( this.currentFolder && this.currentFolder.parent )
16769
+ {
16770
+ this.path.push( this.currentFolder.id );
16497
16771
 
16498
- push_parents_id( data );
16772
+ const push_parents_id = i => {
16773
+ if( !i ) return;
16774
+ this.path.push( i.parent ? i.id : '@' );
16775
+ push_parents_id( i.parent );
16776
+ };
16777
+
16778
+ push_parents_id( this.currentFolder.parent );
16779
+ }
16780
+ else
16781
+ {
16782
+ this.path.push( '@' );
16783
+ }
16499
16784
 
16500
16785
  LX.emit( "@on_folder_change", this.path.reverse().join('/') );
16501
16786
  }
@@ -16533,24 +16818,62 @@ class AssetView {
16533
16818
  switch( event.type )
16534
16819
  {
16535
16820
  case LX.TreeEvent.NODE_SELECTED:
16536
- if( !event.multiple )
16821
+ {
16822
+ if( event.multiple )
16537
16823
  {
16538
- this._enterFolder( node );
16824
+ return;
16539
16825
  }
16540
16826
  if( !node.parent )
16541
16827
  {
16542
- this.prevData.push( this.currentData );
16828
+ if( this.currentFolder )
16829
+ {
16830
+ this.prevData.push( this.currentFolder );
16831
+ }
16832
+
16833
+ this.currentFolder = null;
16543
16834
  this.currentData = this.data;
16544
16835
  this._refreshContent();
16836
+ this._updatePath();
16837
+ }
16838
+ else
16839
+ {
16840
+ this._enterFolder( node.type === "folder" ? node : node.parent );
16841
+
16842
+ this._previewAsset( node );
16545
16843
 
16546
- this.path = ['@'];
16547
- LX.emit("@on_folder_change", this.path.join('/'));
16844
+ if( node.type !== "folder" )
16845
+ {
16846
+ this.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16847
+ const dom = node.domEl;
16848
+ dom?.classList.add( 'selected' );
16849
+ }
16850
+
16851
+ this.selectedItem = node;
16548
16852
  }
16549
16853
  break;
16854
+ }
16550
16855
  case LX.TreeEvent.NODE_DRAGGED:
16551
- node.folder = value;
16856
+ {
16857
+ if( node.parent )
16858
+ {
16859
+ const idx = node.parent.children.indexOf( node );
16860
+ node.parent.children.splice( idx, 1 );
16861
+ }
16862
+
16863
+ node.folder = node.parent = value;
16864
+
16865
+ if( !value.children ) value.children = [];
16866
+
16867
+ value.children.push( node );
16868
+
16869
+ if( this.onItemDragged )
16870
+ {
16871
+ this.onItemDragged( node, value );
16872
+ }
16873
+
16552
16874
  this._refreshContent();
16553
16875
  break;
16876
+ }
16554
16877
  }
16555
16878
  },
16556
16879
  });
@@ -16647,22 +16970,17 @@ class AssetView {
16647
16970
  value: "Left",
16648
16971
  icon: "ArrowLeft",
16649
16972
  callback: domEl => {
16650
- if(!this.prevData.length) return;
16651
- this.nextData.push( this.currentData );
16652
- this.currentData = this.prevData.pop();
16653
- this._refreshContent();
16654
- this._updatePath( this.currentData );
16973
+ if( !this.prevData.length || !this.currentFolder ) return;
16974
+ this.nextData.push( this.currentFolder );
16975
+ this._enterFolder( this.prevData.pop(), false );
16655
16976
  }
16656
16977
  },
16657
16978
  {
16658
16979
  value: "Right",
16659
16980
  icon: "ArrowRight",
16660
16981
  callback: domEl => {
16661
- if(!this.nextData.length) return;
16662
- this.prevData.push( this.currentData );
16663
- this.currentData = this.nextData.pop();
16664
- this._refreshContent();
16665
- this._updatePath( this.currentData );
16982
+ if( !this.nextData.length || !this.currentFolder ) return;
16983
+ this._enterFolder( this.nextData.pop() );
16666
16984
  }
16667
16985
  },
16668
16986
  {
@@ -16673,7 +16991,7 @@ class AssetView {
16673
16991
  ], { noSelection: true } );
16674
16992
 
16675
16993
  this.toolsPanel.addText(null, this.path.join('/'), null, {
16676
- inputClass: "nobg", disabled: true, signal: "@on_folder_change",
16994
+ width: "75%", inputClass: "nobg", disabled: true, signal: "@on_folder_change",
16677
16995
  style: { fontWeight: "600", fontSize: "15px" }
16678
16996
  });
16679
16997
 
@@ -16710,7 +17028,6 @@ class AssetView {
16710
17028
 
16711
17029
  _refreshContent( searchValue, filter ) {
16712
17030
 
16713
- const isGridLayout = ( this.layout == AssetView.LAYOUT_GRID ); // default
16714
17031
  const isCompactLayout = ( this.layout == AssetView.LAYOUT_COMPACT );
16715
17032
  const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
16716
17033
 
@@ -16718,268 +17035,6 @@ class AssetView {
16718
17035
  this.searchValue = searchValue ?? ( this.searchValue ?? "" );
16719
17036
  this.content.innerHTML = "";
16720
17037
  this.content.className = `lexassetscontent${ isCompactLayout ? " compact" : ( isListLayout ? " list" : "" ) }`;
16721
- let that = this;
16722
-
16723
- const _addItem = function( item )
16724
- {
16725
- const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
16726
- const extension = LX.getExtension( item.id );
16727
- const isFolder = type === "Folder";
16728
-
16729
- let itemEl = document.createElement('li');
16730
- itemEl.className = "lexassetitem " + item.type.toLowerCase();
16731
- itemEl.tabIndex = -1;
16732
- that.content.appendChild( itemEl );
16733
-
16734
- if( item.lastModified && !item.lastModifiedDate )
16735
- {
16736
- item.lastModifiedDate = that._lastModifiedToStringDate( item.lastModified );
16737
- }
16738
-
16739
- if( !that.useNativeTitle )
16740
- {
16741
- let desc = document.createElement( 'span' );
16742
- desc.className = 'lexitemdesc';
16743
- desc.id = `floatingTitle_${ item.id }`;
16744
- desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
16745
- that.content.appendChild( desc );
16746
-
16747
- itemEl.addEventListener( "mousemove", e => {
16748
-
16749
- if( !isGridLayout )
16750
- {
16751
- return;
16752
- }
16753
-
16754
- const dialog = itemEl.closest('dialog');
16755
- const rect = itemEl.getBoundingClientRect();
16756
- const targetRect = e.target.getBoundingClientRect();
16757
-
16758
- let localOffsetX = rect.x + e.offsetX;
16759
- let localOffsetY = rect.y + e.offsetY;
16760
-
16761
- if( dialog )
16762
- {
16763
- const dialogRect = dialog.getBoundingClientRect();
16764
- localOffsetX -= dialogRect.x;
16765
- localOffsetY -= dialogRect.y;
16766
- }
16767
-
16768
- if( e.target.classList.contains( "lexassettitle" ) )
16769
- {
16770
- localOffsetY += ( targetRect.y - rect.y );
16771
- }
16772
-
16773
- desc.style.left = ( localOffsetX ) + "px";
16774
- desc.style.top = ( localOffsetY - 36 ) + "px";
16775
- } );
16776
- }
16777
- else
16778
- {
16779
- itemEl.title = type + ": " + item.id;
16780
- }
16781
-
16782
- if( that.allowMultipleSelection )
16783
- {
16784
- let checkbox = document.createElement( 'input' );
16785
- checkbox.type = "checkbox";
16786
- checkbox.className = "lexcheckbox";
16787
- checkbox.checked = item.selected;
16788
- checkbox.addEventListener('change', ( e, v ) => {
16789
- item.selected = !item.selected;
16790
- if( that.onevent )
16791
- {
16792
- const event = new AssetViewEvent(AssetViewEvent.ASSET_CHECKED, e.shiftKey ? [item] : item );
16793
- event.multiple = !!e.shiftKey;
16794
- that.onevent( event );
16795
- }
16796
- e.stopPropagation();
16797
- e.stopImmediatePropagation();
16798
- });
16799
-
16800
- itemEl.appendChild( checkbox );
16801
- }
16802
-
16803
- let title = document.createElement('span');
16804
- title.className = "lexassettitle";
16805
- title.innerText = item.id;
16806
- itemEl.appendChild( title );
16807
-
16808
- if( !that.skipPreview )
16809
- {
16810
- if( item.type === 'video' )
16811
- {
16812
- const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
16813
- itemVideo.setAttribute( 'disablePictureInPicture', false );
16814
- itemVideo.setAttribute( 'disableRemotePlayback', false );
16815
- itemVideo.setAttribute( 'loop', true );
16816
- itemVideo.setAttribute( 'async', true );
16817
- itemVideo.style.transition = 'opacity 0.2s ease-out';
16818
- itemVideo.style.opacity = item.preview ? '0' : '1';
16819
- itemVideo.src = item.src;
16820
- itemVideo.volume = item.videoVolume ?? 0.4;
16821
- }
16822
-
16823
- let preview = null;
16824
-
16825
- const previewSrc = item.preview ?? item.src;
16826
- const hasImage = previewSrc && (
16827
- (() => {
16828
- const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
16829
- return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
16830
- })()
16831
- || previewSrc.startsWith( 'data:image/' )
16832
- );
16833
-
16834
- if( hasImage || isFolder || !isGridLayout )
16835
- {
16836
- const defaultPreviewPath = `${ that.rootPath }images/file.png`;
16837
- const defaultFolderPath = `${ that.rootPath }images/folder.png`;
16838
-
16839
- preview = document.createElement('img');
16840
- let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
16841
- preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
16842
- itemEl.appendChild( preview );
16843
- }
16844
- else
16845
- {
16846
- preview = document.createElement( 'svg' );
16847
- preview.className = 'asset-file-preview';
16848
- itemEl.appendChild( preview );
16849
-
16850
- let textEl = document.createElement( 'text' );
16851
- textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `.${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
16852
- preview.appendChild( textEl );
16853
-
16854
- var newLength = textEl.innerText.length;
16855
- var charsPerLine = 2.5;
16856
- var newEmSize = charsPerLine / newLength;
16857
- var textBaseSize = 64;
16858
-
16859
- if( newEmSize < 1 )
16860
- {
16861
- var newFontSize = newEmSize * textBaseSize;
16862
- textEl.style.fontSize = newFontSize + 'px';
16863
- preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
16864
- }
16865
- }
16866
- }
16867
-
16868
- // Add item type info
16869
- let itemInfoHtml = type;
16870
-
16871
- if( isListLayout )
16872
- {
16873
- if( item.bytesize ) itemInfoHtml += ` | ${ LX.formatBytes( item.bytesize ) }`;
16874
- if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
16875
- }
16876
-
16877
- LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
16878
-
16879
- itemEl.addEventListener('click', function( e ) {
16880
- e.stopImmediatePropagation();
16881
- e.stopPropagation();
16882
-
16883
- const isDoubleClick = ( e.detail == LX.MOUSE_DOUBLE_CLICK );
16884
-
16885
- if( !isDoubleClick )
16886
- {
16887
- if( !e.shiftKey )
16888
- {
16889
- that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16890
- }
16891
-
16892
- this.classList.add( 'selected' );
16893
- that.selectedItem = item;
16894
-
16895
- if( !that.skipPreview )
16896
- {
16897
- that._previewAsset( item );
16898
- }
16899
- }
16900
- else if( isFolder )
16901
- {
16902
- that._enterFolder( item );
16903
- return;
16904
- }
16905
-
16906
- if( that.onevent )
16907
- {
16908
- const event = new AssetViewEvent(isDoubleClick ? AssetViewEvent.ASSET_DBLCLICKED : AssetViewEvent.ASSET_SELECTED, e.shiftKey ? [item] : item );
16909
- event.multiple = !!e.shiftKey;
16910
- that.onevent( event );
16911
- }
16912
- });
16913
-
16914
- if( that.contextMenu )
16915
- {
16916
- itemEl.addEventListener('contextmenu', function( e ) {
16917
- e.preventDefault();
16918
-
16919
- const multiple = that.content.querySelectorAll('.selected').length;
16920
-
16921
- LX.addContextMenu( multiple > 1 ? (multiple + " selected") :
16922
- isFolder ? item.id : item.type, e, m => {
16923
- if( multiple <= 1 )
16924
- {
16925
- m.add("Rename");
16926
- }
16927
- if( !isFolder )
16928
- {
16929
- m.add("Clone", that._cloneItem.bind( that, item ));
16930
- }
16931
- if( multiple <= 1 )
16932
- {
16933
- m.add("Properties");
16934
- }
16935
- m.add("");
16936
- m.add("Delete", that._deleteItem.bind( that, item ));
16937
- });
16938
- });
16939
- }
16940
-
16941
- itemEl.addEventListener("dragstart", function( e ) {
16942
- e.preventDefault();
16943
- }, false );
16944
-
16945
- itemEl.addEventListener( "mouseenter", ( e ) => {
16946
-
16947
- if( !that.useNativeTitle && isGridLayout )
16948
- {
16949
- const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16950
- if( desc ) desc.style.display = "unset";
16951
- }
16952
-
16953
- if( item.type !== "video" ) return;
16954
- e.preventDefault();
16955
- const video = itemEl.querySelector( "video" );
16956
- video.style.opacity = "1";
16957
- video.play();
16958
- } );
16959
-
16960
- itemEl.addEventListener( "mouseleave", ( e ) => {
16961
-
16962
- if( !that.useNativeTitle && isGridLayout )
16963
- {
16964
- setTimeout( () => {
16965
- const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16966
- if( desc ) desc.style.display = "none";
16967
- }, 100 );
16968
- }
16969
-
16970
- if( item.type !== "video" ) return;
16971
- e.preventDefault();
16972
- const video = itemEl.querySelector( "video" );
16973
- video.pause();
16974
- video.currentTime = 0;
16975
- if( item.preview )
16976
- {
16977
- video.style.opacity = "0";
16978
- }
16979
- } );
16980
-
16981
- return itemEl;
16982
- };
16983
17038
 
16984
17039
  const fr = new FileReader();
16985
17040
 
@@ -17015,7 +17070,7 @@ class AssetView {
17015
17070
  } });
17016
17071
  }else
17017
17072
  {
17018
- item.domEl = _addItem( item );
17073
+ item.domEl = this.addItem( item, null, false );
17019
17074
  }
17020
17075
  }
17021
17076
 
@@ -17036,6 +17091,11 @@ class AssetView {
17036
17091
 
17037
17092
  _previewAsset( file ) {
17038
17093
 
17094
+ if( this.skipPreview )
17095
+ {
17096
+ return;
17097
+ }
17098
+
17039
17099
  const is_base_64 = file.src && file.src.includes("data:image/");
17040
17100
 
17041
17101
  this.previewPanel.clear();
@@ -17050,6 +17110,11 @@ class AssetView {
17050
17110
  }
17051
17111
  }
17052
17112
 
17113
+ if( file.lastModified && !file.lastModifiedDate )
17114
+ {
17115
+ file.lastModifiedDate = this._lastModifiedToStringDate( file.lastModified );
17116
+ }
17117
+
17053
17118
  const options = { disabled: true };
17054
17119
 
17055
17120
  this.previewPanel.addText("Filename", file.id, null, options);
@@ -17155,15 +17220,27 @@ class AssetView {
17155
17220
  this._refreshContent();
17156
17221
  }
17157
17222
 
17158
- _enterFolder( folderItem ) {
17223
+ _enterFolder( folderItem, storeCurrent = true ) {
17224
+
17225
+ const child = this.currentData[ 0 ];
17226
+ const sameFolder = child?.parent?.id === folderItem.id;
17227
+
17228
+ if( storeCurrent )
17229
+ {
17230
+ this.prevData.push( this.currentFolder ?? { id: "/", children: this.data } );
17231
+ }
17159
17232
 
17160
- this.prevData.push( this.currentData );
17161
- this.currentData = folderItem.children;
17233
+ this.currentFolder = folderItem;
17234
+ this.currentData = this.currentFolder.children;
17162
17235
  this.contentPage = 1;
17163
- this._refreshContent();
17236
+
17237
+ if( !sameFolder )
17238
+ {
17239
+ this._refreshContent();
17240
+ }
17164
17241
 
17165
17242
  // Update path
17166
- this._updatePath(this.currentData);
17243
+ this._updatePath();
17167
17244
 
17168
17245
  // Trigger event
17169
17246
  if( this.onevent )
@@ -17191,7 +17268,16 @@ class AssetView {
17191
17268
  this.onevent( event );
17192
17269
  }
17193
17270
 
17194
- this.tree.refresh();
17271
+ if( !this.skipBrowser )
17272
+ {
17273
+ this.tree.refresh();
17274
+ }
17275
+
17276
+ if( this.previewPanel )
17277
+ {
17278
+ this.previewPanel.clear();
17279
+ }
17280
+
17195
17281
  this._processData( this.data );
17196
17282
  }
17197
17283
 
@@ -17219,14 +17305,68 @@ class AssetView {
17219
17305
  this._processData( this.data );
17220
17306
  }
17221
17307
 
17308
+ _renameItem( item ) {
17309
+
17310
+ const idx = this.currentData.indexOf( item );
17311
+ if( idx < 0 )
17312
+ {
17313
+ return;
17314
+ }
17315
+
17316
+ const oldName = item.id;
17317
+ const wasSelected = item.domEl.hasClass( "selected" );
17318
+
17319
+ const onRename = ( value ) =>
17320
+ {
17321
+ p.destroy();
17322
+
17323
+ const hoverTitle = this.content.querySelector( `#floatingTitle_${ item.id.replace( /\s/g, '_' ).replaceAll( ".", "_" ) }` );
17324
+ hoverTitle.remove();
17325
+ item.domEl.remove();
17326
+
17327
+ item.id = value;
17328
+ item.domEl = this.addItem( item, idx * 2 );
17329
+
17330
+ if( this.onevent )
17331
+ {
17332
+ const event = new AssetViewEvent( AssetViewEvent.ASSET_RENAMED, item, oldName );
17333
+ this.onevent( event );
17334
+ }
17335
+
17336
+ if( wasSelected )
17337
+ {
17338
+ this._previewAsset( item );
17339
+ }
17340
+
17341
+ if( !this.skipBrowser )
17342
+ {
17343
+ this.tree.refresh();
17344
+ }
17345
+
17346
+ this._processData( this.data );
17347
+ };
17348
+
17349
+ let newName = item.id;
17350
+ const panel = new LX.Panel();
17351
+ panel.addText( null, item.id, ( v, e ) => {
17352
+ newName = v;
17353
+ if( e.constructor === KeyboardEvent ) onRename( v );
17354
+ });
17355
+ panel.addButton( null, "Save", ( v ) => {
17356
+ onRename( newName );
17357
+ }, { buttonClass: "contrast" });
17358
+
17359
+ const p = new LX.Popover( item.domEl, [ panel ], { align: "center", side: "bottom", sideOffset: -128 });
17360
+ }
17361
+
17222
17362
  _lastModifiedToStringDate( lm ) {
17223
17363
  const d = new Date( lm ).toLocaleString();
17224
17364
  return d.substring( 0, d.indexOf( ',' ) );
17225
17365
  }
17226
17366
  }
17227
17367
 
17228
- LX.AssetView = AssetView;
17229
-
17368
+ LX.AssetView = AssetView;
17369
+
17230
17370
  // tour.js @jxarco
17231
17371
 
17232
17372
  class Tour {
@@ -17524,6 +17664,6 @@ class Tour {
17524
17664
  } );
17525
17665
  }
17526
17666
  }
17527
- LX.Tour = Tour;
17528
-
17529
- export { ADD_CUSTOM_COMPONENT, Area, AssetView, AssetViewEvent, BaseComponent, Branch, LX, Menubar, Panel, Sidebar, Tour };
17667
+ LX.Tour = Tour;
17668
+
17669
+ export { ADD_CUSTOM_COMPONENT, Area, AssetView, AssetViewEvent, BaseComponent, Branch, LX, Menubar, Panel, Sidebar, Tour };