Skip to content

Commit a098e73

Browse files
committed
Add support for Albums
1 parent c948f16 commit a098e73

10 files changed

Lines changed: 293 additions & 136 deletions

File tree

BlazorDiffusion.ServiceInterface/DataService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ public async Task<object> Any(AnonData request)
5656
};
5757
}
5858

59+
public async Task<object> Any(GetAlbumIds request)
60+
{
61+
var topAlbumIds = await Db.ColumnAsync<int>(Db.From<Album>()
62+
.Where(x => x.DeletedDate == null)
63+
.OrderByDescending(x => new { x.Score, x.Id })
64+
.Take(1000)
65+
.Select(x => x.Id));
66+
67+
return new GetAlbumIdsResponse
68+
{
69+
Results = topAlbumIds
70+
};
71+
}
72+
5973
public async Task<object> Any(UserData request)
6074
{
6175
var session = await SessionAsAsync<CustomUserSession>();

BlazorDiffusion.ServiceModel/AppData.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class AppData
3434

3535
public class AppSource
3636
{
37+
public const string Albums = "albums";
3738
public const string Top = "top";
3839
public const string User = "user";
3940
public const string InAlbum = "in";

BlazorDiffusion.ServiceModel/SearchData.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ public class AnonDataResponse
6868
public ResponseStatus ResponseStatus { get; set; }
6969
}
7070

71+
public class GetAlbumIds : IReturn<GetAlbumIdsResponse>
72+
{
73+
}
74+
75+
public class GetAlbumIdsResponse
76+
{
77+
public List<int> Results { get; set; }
78+
}
7179

7280
[ValidateIsAuthenticated]
7381
public class UserData : IReturn<UserDataResponse> {}

BlazorDiffusion/Pages/Albums.razor

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
@page "/albums"
2+
@using Ljbc1994.Blazor.IntersectionObserver.Components
3+
@inherits AppAuthComponentBase
4+
5+
<Home Page="AppPage.Search" class="">
6+
7+
<div class="my-4 flex justify-center">
8+
<div class="w-full sm:w-1/3 flex justify-center items-center align-middle whitespace-nowrap">
9+
<div class=@ClassNames("z-20 mb-4 overflow-hidden rounded sm:rounded-md text-center")>
10+
<label for="steps-range" class="block text-sm font-medium text-gray-600 dark:text-gray-400">@UserState.AppPrefs.ArtifactGalleryColumns columns</label>
11+
<input id="steps-range" @bind="UserState.AppPrefs.ArtifactGalleryColumns" @bind:event="oninput" @onchange="SaveAppPrefsAsync"
12+
type="range" min="1" max="12" step="1" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700">
13+
</div>
14+
</div>
15+
</div>
16+
17+
<div class=@ClassNames("grid", AppCss.GetGridClass(UserState.AppPrefs.ArtifactGalleryColumns))>
18+
@foreach (var album in results)
19+
{
20+
var artifact = UserState.GetAlbumCoverArtifact(album);
21+
@if (artifact != null)
22+
{
23+
<div @key=@album.Id>
24+
<NavLink href=@($"/?album={album.AlbumRef}&source={AppSource.Albums}")
25+
class=@ClassNames("overflow-hidden flex justify-center")>
26+
<div class="relative sm:p-2 flex flex-col cursor-pointer items-center" style=@($"width:512px;height:512px")>
27+
<ArtifactImage Artifact="artifact" LazyLoad="true"
28+
class=@ClassNames("flex rounded sm:rounded-xl w-full h-full") ImageClass="object-cover" />
29+
30+
<div class="absolute top-0 left-0 w-full h-full group select-none overflow-hidden sm:m-1 rounded sm:rounded-xl">
31+
<div class="w-full h-full absolute inset-0 z-10 block text-zinc-100 drop-shadow pointer-events-none line-clamp sm:px-2 sm:pb-2 text-sm opacity-0 group-hover:opacity-40 transition duration-300 ease-in-out bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-gray-700 via-gray-900 to-black"></div>
32+
<div class="absolute w-full h-full flex z-10 text-zinc-100 justify-between drop-shadow opacity-0 group-hover:opacity-100 transition-opacity sm:mb-1 text-sm">
33+
<div class="relative w-full h-full overflow-hidden flex flex-col justify-between overflow-hidden">
34+
<div></div>
35+
<div>
36+
<div class="hidden sm:flex bg-white/40 bg-black/40 sm:pt-2 sm:pl-4 sm:pb-4 sm:pr-4 w-full">
37+
<div class="w-full">
38+
<h2 class="truncate text-base font-medium text-gray-900 dark:text-gray-200 text-center">@album.Name</h2>
39+
<div class="mt-1">
40+
<p class="truncate text-xs text-gray-500"></p>
41+
</div>
42+
</div>
43+
</div>
44+
</div>
45+
</div>
46+
</div>
47+
</div>
48+
</div>
49+
</NavLink>
50+
</div>
51+
}
52+
}
53+
</div>
54+
55+
<div @ref="BottomElement" class="flex justify-center">
56+
@if (api.IsLoading)
57+
{
58+
<Loading class="text-gray-300 font-normal" ImageClass="w-7 h-7 mt-1.5" Message="loading..." />
59+
}
60+
</div>
61+
62+
</Home>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using BlazorDiffusion.ServiceModel;
2+
using BlazorDiffusion.Shared;
3+
using BlazorDiffusion.UI;
4+
using Ljbc1994.Blazor.IntersectionObserver;
5+
using Microsoft.AspNetCore.Components;
6+
7+
namespace BlazorDiffusion.Pages;
8+
9+
public partial class Albums : AppAuthComponentBase
10+
{
11+
ApiResult<GetAlbumIdsResponse> api = new();
12+
13+
List<AlbumResult> results = new();
14+
public ElementReference BottomElement { get; set; }
15+
IntersectionObserver? bottomObserver;
16+
[Inject] IIntersectionObserverService ObserverService { get; set; } = default!;
17+
[Inject] ILogger<Favorites> Log { get; set; } = default!;
18+
19+
bool hasMore;
20+
21+
protected override async Task OnParametersSetAsync()
22+
{
23+
await base.OnParametersSetAsync();
24+
25+
api = await ApiAsync(new GetAlbumIds());
26+
if (api.Succeeded)
27+
{
28+
results = await UserState.GetAlbumsByIdsAsync(api.Response!.Results.Take(UserState.InitialTake));
29+
hasMore = results.Count >= UserState.InitialTake;
30+
}
31+
}
32+
async Task SaveAppPrefsAsync()
33+
{
34+
await UserState.SaveAppPrefsAsync();
35+
StateHasChanged();
36+
}
37+
38+
async Task fetchResults(int count)
39+
{
40+
log("Albums Likes fetchResults(): {0} < {1}", results.Count, api.Response?.Results.Count ?? 0);
41+
var nextResults = await UserState.GetAlbumsByIdsAsync(api.Response!.Results.Take(count));
42+
hasMore = nextResults.Count >= count;
43+
setResults(nextResults);
44+
}
45+
46+
void setResults(List<AlbumResult> results)
47+
{
48+
this.results = results;
49+
StateHasChanged();
50+
}
51+
52+
async Task loadMore()
53+
{
54+
log("Albums loadMore({0}) {1}...", hasMore, results.Count + UserState.NextPage);
55+
if (hasMore)
56+
{
57+
await fetchResults(results.Count + UserState.NextPage);
58+
}
59+
}
60+
61+
public async Task SetupObserver()
62+
{
63+
try
64+
{
65+
bottomObserver = await ObserverService.Observe(BottomElement, async (entries) =>
66+
{
67+
var entry = entries.FirstOrDefault();
68+
if (entry?.IsIntersecting == true)
69+
{
70+
await loadMore();
71+
}
72+
StateHasChanged();
73+
});
74+
}
75+
catch (Exception e)
76+
{
77+
// throws on initial load
78+
Log.LogError("Albums ObserverService.Observe(BottomElement): {0}", e.ToString());
79+
}
80+
}
81+
82+
}

BlazorDiffusion/Pages/Index.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
</NavLink>
9797
}
9898
}
99+
<NavLink href="/albums" class="text-xs sm:text-sm text-gray-500 dark:hover:text-gray-300 whitespace-nowrap w-16 sm:w-24 text-center pb-1">more</NavLink>
99100
</div>
100101
</div>
101102

BlazorDiffusion/Shared/ArtifactGallery.razor

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,7 @@
3535
}
3636
</div>
3737

38-
@{
39-
// tailwind needs to see full classses
40-
var colCls = new Dictionary<string, string> {
41-
["1"] = "grid-cols-1",
42-
["2"] = "grid-cols-2",
43-
["3"] = "grid-cols-3",
44-
["4"] = "grid-cols-4",
45-
["5"] = "grid-cols-5",
46-
["6"] = "grid-cols-6",
47-
["7"] = "grid-cols-7",
48-
["8"] = "grid-cols-8",
49-
["9"] = "grid-cols-9",
50-
["10"] = "grid-cols-10",
51-
["11"] = "grid-cols-11",
52-
["12"] = "grid-cols-12",
53-
};
54-
}
55-
<div class=@ClassNames("grid", colCls.TryGetValue(UserState.AppPrefs.ArtifactGalleryColumns, out var cls) ? cls : "grid-cols-6")>
38+
<div class=@ClassNames("grid", AppCss.GetGridClass(UserState.AppPrefs.ArtifactGalleryColumns))>
5639
@foreach (var artifact in Artifacts.OrEmpty())
5740
{
5841
<div @key=@artifact.Id class=@ClassNames(

BlazorDiffusion/UI/AppCss.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using Grpc.Core;
2+
3+
namespace BlazorDiffusion.UI;
4+
5+
public static class AppCss
6+
{
7+
// tailwind needs to see full classses
8+
static Dictionary<string, string> GridClasses = new()
9+
{
10+
["1"] = "grid-cols-1",
11+
["2"] = "grid-cols-2",
12+
["3"] = "grid-cols-3",
13+
["4"] = "grid-cols-4",
14+
["5"] = "grid-cols-5",
15+
["6"] = "grid-cols-6",
16+
["7"] = "grid-cols-7",
17+
["8"] = "grid-cols-8",
18+
["9"] = "grid-cols-9",
19+
["10"] = "grid-cols-10",
20+
["11"] = "grid-cols-11",
21+
["12"] = "grid-cols-12",
22+
};
23+
24+
public static string GetGridClass(string columns)
25+
{
26+
return GridClasses.TryGetValue(columns, out var cls)
27+
? cls
28+
: "grid-cols-6";
29+
}
30+
}

BlazorDiffusion/UI/UserState.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,16 @@ public async Task LoadArtifactsAsync(IEnumerable<int> artifactIds)
241241

242242
public async Task<List<AlbumResult>> GetLikedAlbumsAsync(int? take = null)
243243
{
244-
var missingIds = new List<int>();
245244
var requestedLikeIds = take != null
246245
? LikedAlbumIds.Take(take.Value).ToList()
247246
: LikedAlbumIds;
247+
return await GetAlbumsByIdsAsync(requestedLikeIds);
248+
}
248249

249-
foreach (var id in requestedLikeIds)
250+
public async Task<List<AlbumResult>> GetAlbumsByIdsAsync(IEnumerable<int> albumIds)
251+
{
252+
var missingIds = new List<int>();
253+
foreach (var id in albumIds)
250254
{
251255
if (GetCachedAlbum(id) == null)
252256
missingIds.Add(id);
@@ -257,7 +261,13 @@ public async Task<List<AlbumResult>> GetLikedAlbumsAsync(int? take = null)
257261
if (api.Response?.Results != null) LoadAlbums(api.Response.Results);
258262
}
259263

260-
var to = LikedAlbumIds.Select(id => GetCachedAlbum(id)).Where(x => x != null).Cast<AlbumResult>().ToList();
264+
var to = albumIds.Select(id => GetCachedAlbum(id))
265+
.Where(x => x != null)
266+
.Cast<AlbumResult>().ToList();
267+
268+
var albumCoverArtifactIds = to.Select(GetAlbumCoverArtifactId);
269+
await LoadArtifactsAsync(albumCoverArtifactIds);
270+
261271
return to;
262272
}
263273

0 commit comments

Comments
 (0)