Transition between loading states in the album Ui
This commit is contained in:
parent
2b03c39dfe
commit
a224d5baf8
@ -1,49 +1,90 @@
|
||||
import { For, Show, createEffect, createMemo, createResource, createSignal, onCleanup, onMount } from "solid-js";
|
||||
import { GetAlbumCover, GetRandomAlbums, LoadRandomAlbums } from "../../wailsjs/go/main/App";
|
||||
import { batch, createEffect, createMemo, createResource, createSignal, onMount } from "solid-js";
|
||||
import { GetAlbumCover, GetRandomAlbums, TriggerAlbumReload } from "../../wailsjs/go/main/App";
|
||||
import { main } from "../../wailsjs/go/models";
|
||||
import { createStore } from "solid-js/store";
|
||||
|
||||
type AlbumsData = {
|
||||
status: "loading" | "ok",
|
||||
albums: Array<main.Album | null>
|
||||
}
|
||||
|
||||
export function Home() {
|
||||
const [hidden, setHidden] = createSignal(true);
|
||||
const [albums, {mutate, refetch}] = createResource<Array<main.Album | null>>(GetRandomAlbums);
|
||||
|
||||
const [albumsStore, setAlbumsStore] = createStore<AlbumsData>({
|
||||
status: "loading",
|
||||
albums: new Array(20).fill(null),
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
// Fade in the UI
|
||||
setTimeout(() => setHidden(false), 150);
|
||||
// Load the albums
|
||||
loadAlbums();
|
||||
});
|
||||
|
||||
const reload = () => {
|
||||
LoadRandomAlbums();
|
||||
mutate((new Array(20)).map(() => null));
|
||||
setTimeout(refetch, 100);
|
||||
// Loads the random albums from Go.
|
||||
// This function, when called multiple times, returns the same set.
|
||||
const loadAlbums = async() => {
|
||||
const response = await GetRandomAlbums();
|
||||
|
||||
// Update the albums
|
||||
batch(() => {
|
||||
for (let i = 0; i < response.length; i += 1) {
|
||||
const album = response[i];
|
||||
|
||||
setAlbumsStore("albums", i, album);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const triggerAlbumReload = () => {
|
||||
// Assign all albums to null
|
||||
batch(() => {
|
||||
for (let i = 0; i < 20; i += 1) {
|
||||
setAlbumsStore("albums", i, null);
|
||||
}
|
||||
});
|
||||
|
||||
TriggerAlbumReload();
|
||||
setTimeout(loadAlbums, 50);
|
||||
};
|
||||
|
||||
const els = albumsStore.albums.map((_, idx) => (<Album albums={albumsStore.albums} idx={idx} />));
|
||||
|
||||
return (
|
||||
<div class={`min-h-screen ${hidden() ? "opacity-0" : "opacity-100"} transition-opacity`}>
|
||||
<h1 class="font-black text-2xl pt-6 pb-4 pl-2">
|
||||
Random albums
|
||||
<button
|
||||
class="text-xs font-normal mx-1 p-1 rounded underline hover:bg-zinc-900"
|
||||
onClick={reload}
|
||||
onClick={triggerAlbumReload}
|
||||
>
|
||||
Reload
|
||||
</button>
|
||||
</h1>
|
||||
<div class="pb-4 overflow-scroll whitespace-nowrap">
|
||||
<For each={albums()}>
|
||||
{(album) => <Album album={album} />}
|
||||
</For>
|
||||
{els}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Album(props: { album: main.Album | null }) {
|
||||
const [coverBytes, {mutate, refetch}] = createResource<Array<number> | null>(async() => GetAlbumCover(props.album?.id ?? ""));
|
||||
function Album(props: { albums: Array<main.Album | null>, idx: number }) {
|
||||
const [coverBytes, {mutate, refetch}] = createResource<Array<number> | null>(async() => GetAlbumCover(props.albums[props.idx]?.id ?? ""));
|
||||
const [albumName, setAlbumName] = createSignal("");
|
||||
const [artistName, setArtistName] = createSignal("");
|
||||
|
||||
const album = createMemo(() => props.albums[props.idx]);
|
||||
|
||||
createEffect(() => {
|
||||
if (!props.album) {
|
||||
const a = album();
|
||||
if (a === null) {
|
||||
mutate(null);
|
||||
return;
|
||||
} else {
|
||||
setAlbumName(a.name);
|
||||
setArtistName(a.albumArtist);
|
||||
}
|
||||
|
||||
refetch();
|
||||
@ -57,27 +98,24 @@ function Album(props: { album: main.Album | null }) {
|
||||
return `data:;base64,${bytes}`;
|
||||
});
|
||||
|
||||
const isNull = createMemo(() => !props.album);
|
||||
const isNull = createMemo(() => !album());
|
||||
const opacity = createMemo(() => `${isNull() ? "opacity-0" : "opacity-100"} transition-opacity`);
|
||||
|
||||
return (
|
||||
<div class="inline-block mx-2 p-1 w-32 rounded bg-zinc-900">
|
||||
<Show when={isNull()}>
|
||||
<div class="w-30 h-30" />
|
||||
</Show>
|
||||
<Show when={!isNull()}>
|
||||
<div class="w-30 h-30" >
|
||||
<img
|
||||
class={`inline-block rounded w-30 h-30 transition-opacity ${coverBytes.state === "ready" ? "opacity-100" : "opacity-0"}`}
|
||||
src={base64Image()}
|
||||
alt=""
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<div class={`text-sm overflow-hidden overflow-ellipsis pt-1 ${opacity()}`}>
|
||||
{props.album?.name ?? "..."}
|
||||
{albumName()}
|
||||
</div>
|
||||
<div class={`text-xs overflow-hidden overflow-ellipsis ${opacity()}`}>
|
||||
{props.album?.albumArtist ?? "..."}
|
||||
{artistName()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
4
frontend/wailsjs/go/main/App.d.ts
vendored
4
frontend/wailsjs/go/main/App.d.ts
vendored
@ -8,6 +8,6 @@ export function GetRandomAlbums():Promise<Array<main.Album>>;
|
||||
|
||||
export function Greet(arg1:string):Promise<string>;
|
||||
|
||||
export function LoadRandomAlbums():Promise<void>;
|
||||
|
||||
export function Login(arg1:string,arg2:string,arg3:string):Promise<boolean>;
|
||||
|
||||
export function TriggerAlbumReload():Promise<void>;
|
||||
|
@ -14,10 +14,10 @@ export function Greet(arg1) {
|
||||
return window['go']['main']['App']['Greet'](arg1);
|
||||
}
|
||||
|
||||
export function LoadRandomAlbums() {
|
||||
return window['go']['main']['App']['LoadRandomAlbums']();
|
||||
}
|
||||
|
||||
export function Login(arg1, arg2, arg3) {
|
||||
return window['go']['main']['App']['Login'](arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function TriggerAlbumReload() {
|
||||
return window['go']['main']['App']['TriggerAlbumReload']();
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func (a *App) Login(server, username, password string) (bool, error) {
|
||||
}
|
||||
|
||||
// Triggers a reload of random albums
|
||||
func (a *App) LoadRandomAlbums() {
|
||||
func (a *App) TriggerAlbumReload() {
|
||||
go loadAlbums(serverUrl)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user