Explorar o código

fix: modal backdrop
WIP: search

HOME %!s(int64=2) %!d(string=hai) anos
pai
achega
b5562c1f7c

+ 1 - 1
FNZCM/FNZCM.BlazorWasm/FnzConst.cs

@@ -2,6 +2,6 @@
 {
     internal static class FnzConst
     {
-        public const string PlaylistPageTarget = "_fnz_playlist";
+        public const string PlayPageTarget = "_fnz_play_target";
     }
 }

+ 5 - 1
FNZCM/FNZCM.BlazorWasm/Models/FeTrack.cs

@@ -1,4 +1,6 @@
-namespace FNZCM.BlazorWasm.Models
+using FNZCM.Shared.Helpers;
+
+namespace FNZCM.BlazorWasm.Models
 {
     public class FeTrack
     {
@@ -21,5 +23,7 @@
         public string Path { get; set; }
 
         public FeMediaTag Tag { get; set; }
+
+        public string GetTitleOrFilename() => (Tag?.Title).NullOrEmptyEscape(Name);
     }
 }

+ 8 - 8
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Browse/DiscDialog.razor

@@ -1,16 +1,14 @@
 @inherits FnzComponentBase
 
 @code {
-    [Parameter, Required] public FeDisc Disc { get; set; }
-
-    [Parameter] public EventCallback<FeTrack> OnAddToPlaylist { get; set; } = EventCallback<FeTrack>.Empty;
-
+    private FeDisc Disc { get; set; }
     private FnzBoostrapModal modalDisc { get; set; }
-}
+    private PlaylistAddDialog dlgPlaylistAdd { get; set; }
 
-@code {
-    public void Show()
+    public void Show(FeDisc disc)
     {
+        Disc = disc;
+        StateHasChanged();
         JSRuntime.InvokeVoidAsync("ResetModalDisc");
         modalDisc.Show();
     }
@@ -45,7 +43,7 @@
                         @foreach (var subSet in (Disc?.TrackSets).KeepNoEmpty().WithIndex())
                         {
                             <div class="tab-pane fade" id="tracks-@subSet.index" role="tabpanel">
-                                <DiscDialogTrackSetTable TrackSet="subSet.item" OnClickAddTrackToList="OnAddToPlaylist"></DiscDialogTrackSetTable>
+                                <DiscDialogTrackSetTable TrackSet="subSet.item" OnAddToPlaylist="dlgPlaylistAdd.Show"></DiscDialogTrackSetTable>
                             </div>
                         }
                         @if (Disc?.Bks != null)
@@ -60,3 +58,5 @@
         </div>
     </Body>
 </FnzBoostrapModal>
+
+<PlaylistAddDialog @ref="dlgPlaylistAdd"></PlaylistAddDialog>

+ 1 - 1
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Browse/DiscDialogBkSilder.razor

@@ -2,7 +2,7 @@
     [Parameter, Required] public FeBk[] Bks { get; set; }
 }
 
-<div id="DiscBkSlider" class="carousel .carousel-dark slide bk-container" data-bs-ride="carousel" data-bs-interval="false">
+<div id="DiscBkSlider" class="carousel .carousel-dark slide bk-container" data-bs-interval="false">
     <div class="carousel-indicators bk-indicators">
         @foreach (var bk in (Bks).KeepNoEmpty().WithIndex())
         {

+ 4 - 4
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Browse/DiscDialogTrackSetTable.razor

@@ -1,6 +1,6 @@
 @code {
     [Parameter, Required] public FeTrackSet TrackSet { get; set; }
-    [Parameter] public EventCallback<FeTrack> OnClickAddTrackToList { get; set; } = EventCallback<FeTrack>.Empty;
+    [Parameter] public EventCallback<FeTrack> OnAddToPlaylist { get; set; } = EventCallback<FeTrack>.Empty;
 }
 
 <table class="table">
@@ -10,7 +10,7 @@
                 <i class="bi bi-file-earmark-music"></i>
             </th>
             <th scope="col" class="p-1">
-                <a href="@TrackSet?.M3U8Path" target="@FnzConst.PlaylistPageTarget" onclick="return BlockDownloadAndOpenHtmlPage(this)">Play all</a>
+                <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>
@@ -27,12 +27,12 @@
                     <FileIcon FileName="@t?.Key"></FileIcon>
                 </td>
                 <td scope="row" class="p-0">
-                    <a href="@t?.Path" target="@FnzConst.PlaylistPageTarget">@((t?.Tag?.Title).NullOrEmptyEscape(t?.Name))</a>
+                    <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="()=>OnClickAddTrackToList.InvokeAsync(t)">
+                    <button type="button" class="btn btn-link" style="padding:0.1rem" @onclick="()=>OnAddToPlaylist.InvokeAsync(t)">
                         <i class="bi bi-folder-plus"></i>
                     </button>
                 </td>

+ 40 - 0
FNZCM/FNZCM.BlazorWasm/UI/Components/HighLightKeyword.razor

@@ -0,0 +1,40 @@
+@inherits FnzComponentBase
+@code {
+    [Parameter, Required] public string Text { get; set; }
+    [Parameter, Required] public IReadOnlyCollection<string> Keywords { get; set; }
+}
+
+@if (string.IsNullOrEmpty(Text) == false)
+{
+    var lowerText = Text.ToLower();
+    for (var index = 0; index < Text.Length; ++index)
+    {
+        bool match = false;
+
+        foreach (var kw in Keywords.Where(p => string.IsNullOrEmpty(p) == false).OrderByDescending(p => p.Length))
+        {
+            match = true;
+            var lowerKw = kw.ToLower();
+            for (var ki = 0; ki < kw.Length; ++ki)
+            {
+                if (index + ki >= Text.Length || lowerText[index + ki] != lowerKw[ki])
+                {
+                    match = false;
+                    break;
+                }
+            }
+
+            if (match)
+            {
+                <span class="text-danger">@Text.Substring(index,kw.Length)</span>
+                index += kw.Length - 1;
+                break;
+            }
+        }
+
+        if (index < Text.Length && match == false)
+        {
+            <span>@Text[index]</span>
+        }
+    }
+}

+ 2 - 3
FNZCM/FNZCM.BlazorWasm/UI/Components/PlaylistAddDialog.razor

@@ -10,13 +10,13 @@
     private string NewListNameClass => string.IsNullOrWhiteSpace(NewListName) ? "is-invalid form-control" : "form-control";
 }
 
-<FnzBoostrapModal @ref="dlgMain" CssClass="modal-md">
+<FnzBoostrapModal @ref="dlgMain" CssClass="modal-md" Keyboard="true">
     <Title>Add to playlist</Title>
     <Body>
         <div class="row w-100 text-center p-2">
             <span>
                 <div>
-                    @((PendingAddTrack?.Tag?.Title).NullOrEmptyEscape(PendingAddTrack?.Name))
+                    @(PendingAddTrack?.GetTitleOrFilename())
                 </div>
                 <small>
                     @PendingAddTrack?.Tag?.Artist
@@ -80,7 +80,6 @@
                     <label>New playlist name</label>
                 }
             </div>
-
             <button type="button" class="btn btn-link text-decoration-none" @onclick="CreateNewPlaylist">
                 Create
             </button>

+ 1 - 6
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/App.razor

@@ -12,7 +12,6 @@
     private ProgressBar ProgressBar4;
 
     private SettingDialog dlgSetting;
-    private PlaylistAddDialog dlgPlaylistAdd;
 
     private enum ViewNames { Browse, Search, Playlists }
     private ViewNames CurrentView { get => LocalStorage.Get<ViewNames>(); set => LocalStorage.Set(value); }
@@ -78,7 +77,7 @@
         switch (CurrentView)
         {
             case ViewNames.Browse:
-                <BrowseView OnAddToPlaylist="ShowPlaylistAdd"></BrowseView>
+                <BrowseView></BrowseView>
                 break;
             case ViewNames.Search:
                 <SearchView></SearchView>
@@ -91,8 +90,6 @@
 
 </div>
 
-<PlaylistAddDialog @ref="dlgPlaylistAdd"></PlaylistAddDialog>
-
 @code {
     private async Task LoadData()
     {
@@ -136,6 +133,4 @@
             LoadingErrorMessage = ex.Message;
         }
     }
-
-    private void ShowPlaylistAdd(FeTrack track) => dlgPlaylistAdd.Show(track);
 }

+ 7 - 16
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Browse/BrowseView.razor

@@ -1,9 +1,11 @@
 @inherits ViewBase
 
-@code {
-    [Parameter] public EventCallback<FeTrack> OnAddToPlaylist { get; set; } = EventCallback<FeTrack>.Empty;
+@code{
+    private DiscDialog dlgDisc;
 }
 
+<DiscDialog @ref="dlgDisc"></DiscDialog>
+
 <div class="row mt-2">
     <div class="col">
         <LibSelector CurrentLibrary="@CurrentLibrary" OnValueChanged="SelectedLibraryChanged"></LibSelector>
@@ -21,19 +23,15 @@
 <div class="row">
     <div class="col-12">
         <div class="row">
-            <DiscCardList Discs="CurrentLibrary?.Discs" OnClick="SelectDisc"></DiscCardList>
+            <DiscCardList Discs="CurrentLibrary?.Discs" OnClick="(d)=>dlgDisc.Show(d)"></DiscCardList>
         </div>
     </div>
 </div>
 
-<DiscDialog @ref="ModalDisc" Disc="CurrentDisc" OnAddToPlaylist="OnAddToPlaylist"></DiscDialog>
 
 @code {
-    private FeLibrary CurrentLibrary { get; set; }
-    private FeDisc CurrentDisc { get; set; }
-    private DiscDialog ModalDisc { get; set; }
-
     private string CurrentLibraryKey { get => LocalStorage.Get<string>(); set => LocalStorage.Set(value); }
+    private FeLibrary CurrentLibrary { get; set; }
 
     protected override async Task OnInitializedAsync()
     {
@@ -52,11 +50,4 @@
         CurrentLibraryKey = lib.Key;
         StateHasChanged();
     }
-
-    private void SelectDisc(FeDisc disc)
-    {
-        CurrentDisc = disc;
-        StateHasChanged();
-        ModalDisc.Show();
-    }
-}
+}

+ 1 - 1
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Browse/LibTrackSet.razor

@@ -12,7 +12,7 @@
     @foreach (var cat in (CurrentLibrary?.Catalogs).KeepNoEmpty())
     {
         <li class="nav-item mb-1 mx-2">
-            <a class="btn btn-link p-2 py-1" href="@cat?.PlaylistPath" target="@FnzConst.PlaylistPageTarget" onclick="return BlockDownloadAndOpenHtmlPage(this)">
+            <a class="btn btn-link p-2 py-1" href="@cat?.PlaylistPath" target="@FnzConst.PlayPageTarget" onclick="return BlockDownloadAndOpenHtmlPage(this)">
                 <small class="font-monospace">@cat?.TotalDuration.SecondToDur() @cat?.TotalBytes.BytesToFileSize()</small>
                 @cat?.Name
             </a>

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

@@ -69,7 +69,7 @@
                                 <td class="align-middle w-100">
                                     <div class="text-nowrap">
                                         <FileIcon FileName="@track.Name"></FileIcon>
-                                        @((track.Tag?.Title).NullOrEmptyEscape(track.Name))
+                                        @track.GetTitleOrFilename()
                                     </div>
                                     <div class="text-nowrap text-muted"> @track.Tag?.Artist</div>
                                 </td>

+ 14 - 12
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Playlist/PlaylistView.razor

@@ -11,7 +11,6 @@
 }
 
 <div class="container mt-3">
-
     @foreach (var item in PlaylistHelper.PlayListLoadSave.KeepNoEmpty())
     {
         if (item.Value != null)
@@ -31,7 +30,6 @@
             </table>
         }
     }
-
 </div>
 
 @code {
@@ -88,16 +86,20 @@
 <FnzBoostrapModal @ref="EditPlaylistDialog" CssClass="modal-sm">
     <Title>Modify playlist</Title>
     <Body>
-        <div class="form-floating row w-100">
-            <InputText class="@EditListNameClass" placeholder="Playlist Name" @oninput="EditPlaylistNameChanged" Value="@CurrentEditPlaylistName" ValueExpression="()=>CurrentEditPlaylistName"></InputText>
-            @if (string.IsNullOrEmpty(CurrentEditPlaylistName))
-            {
-                <label class="text-warning">Please enter playlist name</label>
-            }
-            else
-            {
-                <label>Playlist Name</label>
-            }
+        <div class="row">
+            <div class="w-100">
+                <div class="form-floating">
+                    <InputText class="@EditListNameClass" placeholder="Playlist Name" @oninput="EditPlaylistNameChanged" Value="@CurrentEditPlaylistName" ValueExpression="()=>CurrentEditPlaylistName"></InputText>
+                    @if (string.IsNullOrEmpty(CurrentEditPlaylistName))
+                    {
+                        <label class="text-warning">Please enter playlist name</label>
+                    }
+                    else
+                    {
+                        <label>Playlist Name</label>
+                    }
+                </div>
+            </div>
         </div>
     </Body>
     <Footer>

+ 66 - 28
FNZCM/FNZCM.BlazorWasm/UI/Views/Default/Search/SearchView.razor

@@ -10,10 +10,16 @@
     private bool isSearching = false;
     private ProgressBar searchProgressBar;
 
-    private string resultText;
-    private IGrouping<FeDisc, FeTrack>[] resultEntries;
+    private static string resultText;
+    private static IGrouping<FeDisc, FeTrack>[] resultEntries;
+
+    private DiscDialog dlgDisc;
+    private PlaylistAddDialog dlgPlaylistAdd;
 }
 
+<DiscDialog @ref="dlgDisc" Disc="CurrentDisc"></DiscDialog>
+<PlaylistAddDialog @ref="dlgPlaylistAdd"></PlaylistAddDialog>
+
 <div class="row">
     <div class="col-12">
         <fieldset class="border rounded-3 p-2">
@@ -26,11 +32,11 @@
                                Value="@searchExpression"
                                ValueExpression="@(()=>searchExpression)"
                                @oninput="SearchChanged"
-                               onsearch="@SearchDone">
+                               onsearch="@SearchGo">
                     </InputText>
                     <label>Search expression</label>
                 </div>
-                <button @onclick="@SearchDone" class="btn btn-outline-primary" type="button">Search</button>
+                <button @onclick="@SearchGo" class="btn btn-outline-primary" type="button">Search</button>
             </div>
             <div class="row mt-3">
                 <label for="staticEmail" class="col-sm-2 col-form-label">Track set</label>
@@ -60,12 +66,12 @@
                     </InputRadioGroup>
                 </div>
             </div>
-            <div class="row mt-3">
-                <label for="staticEmail" class="col-sm-2 col-form-label">Debug</label>
-                <div class="col-sm-10">
-                    <button @onclick="()=>isSearching=true">Show progressbar</button>
-                </div>
+            @*<div class="row mt-3">
+            <label for="staticEmail" class="col-sm-2 col-form-label">Debug</label>
+            <div class="col-sm-10">
+            <button class="btn btn-primary" @onclick="()=>isSearching=true">Show progressbar</button>
             </div>
+            </div>*@
         </fieldset>
     </div>
 </div>
@@ -88,20 +94,48 @@
             <legend class="float-none w-auto px-2 d-flex flex-row align-items-center">
                 <span>Result</span>
             </legend>
-            <span>@resultText</span>
+
+            <div class="mb-3 text-center">@resultText</div>
+
             @if (resultEntries?.Length > 0)
             {
                 foreach (var item in resultEntries)
                 {
                     var disc = item.Key;
 
-                    <div>
-                        @item.Key.Name
-                        @foreach (var tr in item)
-                        {
-                            <div> @tr.Name </div>
-                        }
-                    </div>
+                    <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>
+                                        </button>
+                                    </td>
+                                </tr>
+                            }
+                        </tbody>
+                    </table>
                 }
             }
         </fieldset>
@@ -109,21 +143,23 @@
 </div>
 
 @code {
-    private async Task SearchDone()
+    private async Task SearchGo()
     {
         isSearching = true;
         StateHasChanged();
 
         await Task.Delay(1);
 
-        var filters = new List<Func<FeTrack, bool>> { p => p.TrackSetKey == searchTrackSetKey };
-
-        //TODO: Expression implement
-        if (string.IsNullOrEmpty(searchExpression) == false) filters.Add(p => p.Name.Contains(searchExpression));
-
         var filteredList = new List<FeTrack>(searchLimitCount);
         var matchedCount = 0;
         var flagPlus = false;
+
+        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));
+        }
+
         for (var i = 0; i < DataSet.AllTracks.Length && isSearching; i++)
         {
             var item = DataSet.AllTracks[i];
@@ -143,6 +179,8 @@
             await searchProgressBar.SetProgress((float)i / DataSet.AllTracks.Length, $"Searching {i + 1}/{DataSet.AllTracks.Length} matched:{matchedCount}");
         }
 
+        //TODO: search in disc name
+
         resultText = $"Result for {searchExpression.NullOrEmptyEscape("<NONE>")} on {searchTrackSetKey} limit {searchLimitCount} of {matchedCount}{(flagPlus ? "+" : "")}";
 
         resultEntries = filteredList
@@ -159,7 +197,8 @@
         if (firstRender)
         {
             AllTrackSet = DataSet.AllTracksSet.GroupBy(p => p.Key).ToDictionary(p => p.Key, p => p.First().Name);
-            await SearchDone();
+            if (resultEntries == null) await SearchGo();
+            else StateHasChanged();
         }
     }
 
@@ -175,7 +214,7 @@
         {
             if (searchTrackSetKey == value) return;
             searchTrackSetKey = value;
-            SearchDone();
+            SearchGo();
         }
     }
 
@@ -186,8 +225,7 @@
         {
             if (searchLimitCount == value) return;
             searchLimitCount = value;
-            SearchDone();
+            SearchGo();
         }
     }
-
-}
+}