Jelajahi Sumber

responsive table for Horizontal Scroll; add highlight when hover

HOME 2 tahun lalu
induk
melakukan
cecdd5bf9f

+ 38 - 37
FNZCM/FNZCM.BlazorWasm/UI/Components/DiscDialogTrackSetTable.razor

@@ -3,41 +3,42 @@
     [Parameter] public EventCallback<FeTrack> OnAddToPlaylist { get; set; } = EventCallback<FeTrack>.Empty;
 }
 
-<table class="table">
-    <thead>
-        <tr>
-            <th scope="col" class="p-1 text-center">
-                <i class="bi bi-file-earmark-music"></i>
-            </th>
-            <th scope="col" class="p-1">
-                <a href="@TrackSet?.M3U8Path" target="@FnzConst.PlayPageTarget" onclick="return BlockDownloadAndOpenHtmlPage(this)">Play all</a>
-            </th>
-            <th scope="col" class="p-1 text-center">@TrackSet?.TotalDuration.SecondToDur()</th>
-            <th scope="col" class="p-1 text-center">@TrackSet?.TotalBytes.BytesToFileSize()</th>
-            <th scope="col" class="p-1 text-center">
-                <i class="bi bi-list-ul"></i>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        @foreach (var t in (TrackSet?.Tracks).KeepNoEmpty())
-        {
-            <tr>
-                <td scope="col" class="p-1 text-center">
-                    <FileIcon FileName="@t?.Key"></FileIcon>
-                </td>
-                <td scope="row" class="p-0">
-                    <a href="@t?.Path" target="@FnzConst.PlayPageTarget">@t?.GetTitleOrFilename()</a>
-                </td>
-                <td class="p-0 text-center">@(t?.Tag?.Duration.SecondToDur() ?? "?")</td>
-                <td class="p-0 text-center">@(t?.Tag?.Length.BytesToFileSize() ?? "?")</td>
-                <td class="p-0 text-center">
-                    <button type="button" class="btn btn-link" style="padding:0.1rem" @onclick="()=>OnAddToPlaylist.InvokeAsync(t)">
-                        <i class="bi bi-folder-plus"></i>
-                    </button>
-                </td>
+<div class="table-responsive">
+    <table class="table">
+        <thead>
+            <tr class="table-primary">
+                <th scope="col" class="p-1 text-center">
+                    <i class="bi bi-file-earmark-music"></i>
+                </th>
+                <th scope="col" class="p-1">
+                    <a href="@TrackSet?.M3U8Path" target="@FnzConst.PlayPageTarget" onclick="return BlockDownloadAndOpenHtmlPage(this)">Play all</a>
+                </th>
+                <th scope="col" class="p-1 text-center">@TrackSet?.TotalDuration.SecondToDur()</th>
+                <th scope="col" class="p-1 text-center">@TrackSet?.TotalBytes.BytesToFileSize()</th>
+                <th scope="col" class="p-1 text-center">
+                    <i class="bi bi-list-ul"></i>
+                </th>
             </tr>
-        }
-    </tbody>
-</table>
-
+        </thead>
+        <tbody>
+            @foreach (var t in (TrackSet?.Tracks).KeepNoEmpty().WithIndex())
+            {
+                <tr class="@(t.index%2==0?"":"table-primary") mouse-hilight">
+                    <td scope="col" class="p-1 text-center">
+                        <FileIcon FileName="@t.item?.Key"></FileIcon>
+                    </td>
+                    <td scope="row" class="p-0 text-nowrap">
+                        <a href="@t.item?.Path" target="@FnzConst.PlayPageTarget">@t.item?.GetTitleOrFilename()</a>
+                    </td>
+                    <td class="p-0 text-center">@(t.item?.Tag?.Duration.SecondToDur() ?? "?")</td>
+                    <td class="p-0 text-center">@(t.item?.Tag?.Length.BytesToFileSize() ?? "?")</td>
+                    <td class="p-0 text-center">
+                        <button type="button" class="btn btn-link" style="padding:0.1rem" @onclick="()=>OnAddToPlaylist.InvokeAsync(t.item)">
+                            <i class="bi bi-folder-plus"></i>
+                        </button>
+                    </td>
+                </tr>
+            }
+        </tbody>
+    </table>
+</div>

+ 101 - 99
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Playlist/PlaylistTableItem.razor

@@ -8,126 +8,128 @@
     private bool IsExpand;
 }
 
-<table class="table w-100">
-    <tbody>
+<div class="table-responsive">
+    <table class="table w-100">
+        <tbody>
 
-        @if (Playlist != null)
-        {
-            var arr = PlaylistHelper[Playlist.Value.Key];
+            @if (Playlist != null)
+            {
+                var arr = PlaylistHelper[Playlist.Value.Key];
 
-            <tr>
-                <td class="w-0" style="width:0" @onclick="()=>{IsExpand=!IsExpand;}">
-                    <button type="button" class="btn btn-primary p-2">
-                        @if (IsExpand)
-                        {
-                            <i class="bi bi-dash-square"></i>
-                        }
-                        else
-                        {
-                            <i class="bi bi-plus-square"></i>
-                        }
-                    </button>
-                </td>
-                <td class="text-left w-100 align-middle" @onclick="()=>{IsExpand=!IsExpand;}" colspan="2">
-                    <div class="text-nowrap">@Playlist.Value.Value</div>
-                    <div class="text-nowrap text-muted">
-                        (@arr.Count)
-                        @arr.Sum(p=>DataSet.AllTracks.Where(q=>q.Path==p).Select(q=>q.Tag?.Duration??0).FirstOrDefault()).SecondToDur()
-                        @arr.Sum(p=>DataSet.AllTracks.Where(q=>q.Path==p).Select(q=>q.Tag?.Length??0).FirstOrDefault()).BytesToFileSize()
-                    </div>
-                </td>
-                <td>
-                    <button type="button" class="btn btn-primary p-2" @onclick="()=>DownloadPlaylist(Playlist.Value.Key)">
-                        <i class="bi bi-download"></i>
-                    </button>
-                </td>
-                <td>
-                    <button type="button" class="btn btn-primary p-2" @onclick="()=>EditPlaylist.InvokeAsync(Playlist.Value.Key)">
-                        <i class="bi bi-pencil-square"></i>
-                    </button>
-                </td>
-                <td class="align-middle text-nowrap">
-                    <button type="button" class="btn btn-primary p-2" @onclick="()=>DeletePlaylist.InvokeAsync(Playlist.Value.Key)">
-                        <i class="bi bi-trash"></i>
-                    </button>
-                </td>
-            </tr>
+                <tr class="table-primary">
+                    <td class="w-0" style="width:0" @onclick="()=>{IsExpand=!IsExpand;}">
+                        <button type="button" class="btn btn-primary p-2">
+                            @if (IsExpand)
+                            {
+                                <i class="bi bi-dash-square"></i>
+                            }
+                            else
+                            {
+                                <i class="bi bi-plus-square"></i>
+                            }
+                        </button>
+                    </td>
+                    <td class="text-left w-100 align-middle" @onclick="()=>{IsExpand=!IsExpand;}" colspan="2">
+                        <div class="text-nowrap">@Playlist.Value.Value</div>
+                        <div class="text-nowrap text-muted">
+                            (@arr.Count)
+                            @arr.Sum(p=>DataSet.AllTracks.Where(q=>q.Path==p).Select(q=>q.Tag?.Duration??0).FirstOrDefault()).SecondToDur()
+                            @arr.Sum(p=>DataSet.AllTracks.Where(q=>q.Path==p).Select(q=>q.Tag?.Length??0).FirstOrDefault()).BytesToFileSize()
+                        </div>
+                    </td>
+                    <td>
+                        <button type="button" class="btn btn-primary p-2" @onclick="()=>DownloadPlaylist(Playlist.Value.Key)">
+                            <i class="bi bi-download"></i>
+                        </button>
+                    </td>
+                    <td>
+                        <button type="button" class="btn btn-primary p-2" @onclick="()=>EditPlaylist.InvokeAsync(Playlist.Value.Key)">
+                            <i class="bi bi-pencil-square"></i>
+                        </button>
+                    </td>
+                    <td class="align-middle text-nowrap">
+                        <button type="button" class="btn btn-primary p-2" @onclick="()=>DeletePlaylist.InvokeAsync(Playlist.Value.Key)">
+                            <i class="bi bi-trash"></i>
+                        </button>
+                    </td>
+                </tr>
 
-            @if (IsExpand)
-            {
-                @foreach (var item in arr.KeepNoEmpty().WithIndex())
+                @if (IsExpand)
                 {
-                    if (item.item != null)
+                    @foreach (var item in arr.KeepNoEmpty().WithIndex())
                     {
-                        var track = DataSet.AllTracks.FirstOrDefault(p => p.Path == item.item);
-                        if (track != null)
+                        if (item.item != null)
                         {
-                            <tr>
-                                <td colspan="2" style="width:0">
-                                    <img src="@track.Disc.CoverPath" style="height:50px" />
-                                </td>
-                                <td class="align-middle w-100">
-                                    <div class="text-nowrap">
-                                        <FileIcon FileName="@track.Name"></FileIcon>
-                                        @track.GetTitleOrFilename()
-                                    </div>
-                                    <div class="text-nowrap text-muted"> @track.Tag?.Artist</div>
-                                </td>
-                                <td class="text-center" colspan="2">
-                                    <div class="text-nowrap">@track.Tag?.Duration.SecondToDur()</div>
-                                    <div class="text-nowrap text-muted"> @track.Tag?.Length.BytesToFileSize()</div>
-                                </td>
-                                <td>
-                                    <button type="button" class="btn btn-primary p-2" @onclick="()=>Remove(Playlist.Value.Key, item.index,item.item)">
-                                        <i class="bi bi-folder-minus"></i>
-                                    </button>
-                                </td>
-                            </tr>
+                            var track = DataSet.AllTracks.FirstOrDefault(p => p.Path == item.item);
+                            if (track != null)
+                            {
+                                <tr class="mouse-hilight">
+                                    <td colspan="2" style="width:0">
+                                        <img src="@track.Disc.CoverPath" style="height:50px" />
+                                    </td>
+                                    <td class="align-middle w-100">
+                                        <div class="text-nowrap">
+                                            <FileIcon FileName="@track.Name"></FileIcon>
+                                            @track.GetTitleOrFilename()
+                                        </div>
+                                        <div class="text-nowrap text-muted"> @track.Tag?.Artist</div>
+                                    </td>
+                                    <td class="text-center" colspan="2">
+                                        <div class="text-nowrap">@track.Tag?.Duration.SecondToDur()</div>
+                                        <div class="text-nowrap text-muted"> @track.Tag?.Length.BytesToFileSize()</div>
+                                    </td>
+                                    <td>
+                                        <button type="button" class="btn btn-primary p-2" @onclick="()=>Remove(Playlist.Value.Key, item.index,item.item)">
+                                            <i class="bi bi-folder-minus"></i>
+                                        </button>
+                                    </td>
+                                </tr>
+                            }
+                            else
+                            {
+                                var uri = new Uri(item.item);
+                                var paths = uri.AbsolutePath.Split('/').Skip(2).ToArray();
+                                <tr>
+                                    <td></td>
+                                    <td><img src="blazor-192.png" style="height:50px" /></td>
+                                    <td class="align-middle w-100">
+                                        <div class="text-nowrap">- broken reference -</div>
+                                        @foreach (var p in paths)
+                                        {
+                                            <div class="text-nowrap text-muted">@Uri.UnescapeDataString(p)</div>
+                                        }
+                                    </td>
+                                    <td></td>
+                                    <td></td>
+                                    <td>
+                                        <button type="button" class="btn btn-primary p-2" @onclick="()=>Remove(Playlist.Value.Key, item.index,item.item)">
+                                            <i class="bi bi-trash"></i>
+                                        </button>
+                                    </td>
+                                    <td></td>
+                                    <td></td>
+                                </tr>
+                            }
                         }
                         else
                         {
-                            var uri = new Uri(item.item);
-                            var paths = uri.AbsolutePath.Split('/').Skip(2).ToArray();
                             <tr>
                                 <td></td>
-                                <td><img src="blazor-192.png" style="height:50px" /></td>
+                                <td></td>
                                 <td class="align-middle w-100">
-                                    <div class="text-nowrap">- broken reference -</div>
-                                    @foreach (var p in paths)
-                                    {
-                                        <div class="text-nowrap text-muted">@Uri.UnescapeDataString(p)</div>
-                                    }
+                                    <div class="text-nowrap">- empty -</div>
                                 </td>
                                 <td></td>
                                 <td></td>
-                                <td>
-                                    <button type="button" class="btn btn-primary p-2" @onclick="()=>Remove(Playlist.Value.Key, item.index,item.item)">
-                                        <i class="bi bi-trash"></i>
-                                    </button>
-                                </td>
-                                <td></td>
                                 <td></td>
                             </tr>
                         }
                     }
-                    else
-                    {
-                        <tr>
-                            <td></td>
-                            <td></td>
-                            <td class="align-middle w-100">
-                                <div class="text-nowrap">- empty -</div>
-                            </td>
-                            <td></td>
-                            <td></td>
-                            <td></td>
-                        </tr>
-                    }
                 }
             }
-        }
-    </tbody>
-</table>
+        </tbody>
+    </table>
+</div>
 
 @code {
     private void DownloadPlaylist(Guid playlistId)

+ 39 - 32
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Search/SearchView.razor

@@ -103,39 +103,45 @@
                 {
                     var disc = item.Key;
 
-                    <table class="table w-100">
-                        <tbody>
-                            <tr>
-                                <td><img src="@disc.CoverPath" style="height:50px" /></td>
-                                <td colspan="4" class="w-100">@item.Key.Name</td>
-                                <td colspan="2" class="text-end">
-                                    <button class="btn btn-primary" @onclick="()=>dlgDisc.Show(disc)">
-                                        <i class="bi bi-window-stack"></i>
-                                    </button>
-                                </td>
-                            </tr>
-
-                            @foreach (var tr in item.OrderBy(p => p.Name))
-                            {
-                                <tr>
-                                    <td></td>
-                                    <td><FileIcon FileName="@tr.Key"></FileIcon></td>
-                                    <td class="w-100">
-                                        <a href="@tr.Path" target="@FnzConst.PlayPageTarget">
-                                            <HighLightKeyword Text="@tr.GetTitleOrFilename()" Keywords="@(new []{ searchExpression})"></HighLightKeyword>
-                                        </a>
-                                    </td>
-                                    <td>@tr.Tag.Duration.SecondToDur()</td>
-                                    <td>@tr.Tag.Length.BytesToFileSize()</td>
-                                    <td class="text-center">
-                                        <button type="button" class="btn btn-link" style="padding:0.1rem" @onclick="()=>dlgPlaylistAdd.Show(tr)">
-                                            <i class="bi bi-folder-plus"></i>
+                    <div class="table-responsive">
+                        <table class="table w-100">
+                            <tbody>
+                                <tr class="table-primary">
+                                    <td><img src="@disc.CoverPath" style="height:50px" /></td>
+                                    <td colspan="2" class="w-100">@item.Key.Name</td>
+                                    <td colspan="2" class="text-end">
+                                        <button class="btn btn-primary" @onclick="()=>dlgDisc.Show(disc)">
+                                            <i class="bi bi-window-stack"></i>
                                         </button>
                                     </td>
                                 </tr>
-                            }
-                        </tbody>
-                    </table>
+
+                                @foreach (var tr in item.OrderBy(p => p.Name))
+                                {
+                                    <tr class="mouse-hilight">
+                                        <td><FileIcon FileName="@tr.Key"></FileIcon></td>
+                                        <td class="w-100 text-nowrap">
+                                            <div>
+                                                <a href="@tr.Path" target="@FnzConst.PlayPageTarget">
+                                                    <HighLightKeyword Text="@tr.GetTitleOrFilename()" Keywords="@(new []{ searchExpression})"></HighLightKeyword>
+                                                </a>
+                                            </div>
+                                            <div class="text-nowrap text-muted">@tr.Tag?.Artist</div>
+                                        </td>
+                                        <td>
+                                            <div class="text-nowrap">@tr.Tag.Duration.SecondToDur()</div>
+                                            <div class="text-nowrap text-muted">@tr.Tag.Length.BytesToFileSize()</div>
+                                        </td>
+                                        <td class="text-center">
+                                            <button type="button" class="btn btn-link" style="padding:0.1rem" @onclick="()=>dlgPlaylistAdd.Show(tr)">
+                                                <i class="bi bi-folder-plus"></i>
+                                            </button>
+                                        </td>
+                                    </tr>
+                                }
+                            </tbody>
+                        </table>
+                    </div>
                 }
             }
         </fieldset>
@@ -156,8 +162,9 @@
 
         var filters = new List<Func<FeTrack, bool>> { p => p.TrackSetKey == searchTrackSetKey };
         //TODO: Expression implement
-        if (string.IsNullOrEmpty(searchExpression) == false) {
-            filters.Add(p => p.GetTitleOrFilename().Contains(searchExpression,StringComparison.OrdinalIgnoreCase));
+        if (string.IsNullOrEmpty(searchExpression) == false)
+        {
+            filters.Add(p => p.GetTitleOrFilename().Contains(searchExpression, StringComparison.OrdinalIgnoreCase));
         }
 
         for (var i = 0; i < DataSet.AllTracks.Length && isSearching; i++)

+ 4 - 0
FNZCM/FNZCM.BlazorWasm/wwwroot/fnz.css

@@ -29,6 +29,10 @@
     background-position: 50% 50%;
 }
 
+tr.mouse-hilight:hover {
+    border-bottom: 1px var(--bs-success);
+}
+
 /* */
 
 .dropdown-menu.show[aria-labelledby=themes] {