When the app starts it verifies all three services sequentially, which could leave the other two login controls looking idle or trigger login actions before their real state is known. Track which service is currently being checked and reflect it in the header: - Add a serviceLoggingIn store (plus setServiceLoggingIn and isServiceLoggingIn helpers) to GlobalVariablesAndHelperFunctions. - Have the loginTo* functions and the startup CheckIf* functions toggle their service in the store (seed all three at startup, clear each as it resolves). - In Header, the login buttons show a spinner with 'Checking AniList' / 'Checking MAL' / 'Checking Simkl' and are disabled while that service is being checked, reverting to the normal 'AniList Login' style label once its state is known. - In the avatar menu, the 'Login to X' row shows a spinner with the matching 'Checking X' text while that service is logging in.
134 lines
5.5 KiB
Svelte
134 lines
5.5 KiB
Svelte
<script lang="ts">
|
|
import Search from "./Search.svelte";
|
|
import {
|
|
aniListLoggedIn,
|
|
loginToAniList,
|
|
loginToMAL,
|
|
loginToSimkl,
|
|
malLoggedIn,
|
|
simklLoggedIn,
|
|
serviceLoggingIn,
|
|
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
|
import AvatarMenu from "./AvatarMenu.svelte";
|
|
import logo from "../assets/images/AniTrackLogo.svg";
|
|
import { link } from "svelte-spa-router";
|
|
|
|
let isAniListLoggedIn: boolean;
|
|
let isSimklLoggedIn: boolean;
|
|
let isMALLoggedIn: boolean;
|
|
let loggingIn: string[] = [];
|
|
|
|
aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value));
|
|
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
|
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
|
serviceLoggingIn.subscribe((value) => (loggingIn = value));
|
|
</script>
|
|
|
|
<nav class="border-gray-200 bg-gray-900">
|
|
<div
|
|
class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4"
|
|
>
|
|
<div class="flex items-center space-x-3 rtl:space-x-reverse">
|
|
<a href="/" use:link
|
|
><img src={logo} class="h-8" alt="AniTrack Logo" /></a
|
|
>
|
|
</div>
|
|
<div
|
|
class="flex items-center min-[950px]:order-2 space-x-3 min-[950px]:space-x-0 rtl:space-x-reverse"
|
|
>
|
|
<div class="min-[950px]:block min-[950px]:mr-4">
|
|
<Search />
|
|
</div>
|
|
<AvatarMenu />
|
|
<button
|
|
on:click={() => {
|
|
let menu = document.querySelector("#navbar-user");
|
|
menu.classList.toggle("hidden");
|
|
}}
|
|
type="button"
|
|
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm rounded-lg min-[950px]:hidden focus:outline-none focus:ring-2 text-gray-400 hover:bg-gray-700 focus:ring-gray-600"
|
|
aria-controls="navbar-user"
|
|
aria-expanded="false"
|
|
>
|
|
<span class="sr-only">Open main menu</span>
|
|
<svg
|
|
class="w-5 h-5"
|
|
aria-hidden="true"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 17 14"
|
|
>
|
|
<path
|
|
stroke="currentColor"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M1 1h15M1 7h15M1 13h15"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div
|
|
class="hidden items-center justify-between w-full pb-4 min-[950px]:pb-0 min-[950px]:flex min-[950px]:w-auto min-[950px]:order-1 border border-gray-700 min-[950px]:border-0 bg-gray-800 min-[950px]:bg-transparent rounded-lg"
|
|
id="navbar-user"
|
|
>
|
|
<ul
|
|
class="flex flex-col font-medium pb-6 min-[950px]:p-0 mt-4 min-[950px]:space-x-8 rtl:space-x-reverse min-[950px]:flex-row min-[950px]:mt-0"
|
|
>
|
|
<li>
|
|
{#if !isAniListLoggedIn}
|
|
<button
|
|
disabled={loggingIn.includes("anilist")}
|
|
on:click={loginToAniList}
|
|
>
|
|
{#if loggingIn.includes("anilist")}
|
|
<span
|
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
|
></span
|
|
>Checking AniList
|
|
{:else}
|
|
AniList Login
|
|
{/if}
|
|
</button>
|
|
{/if}
|
|
{#if !isMALLoggedIn}
|
|
<button
|
|
disabled={loggingIn.includes("mal")}
|
|
on:click={loginToMAL}
|
|
>
|
|
{#if loggingIn.includes("mal")}
|
|
<span
|
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
|
></span
|
|
>Checking MAL
|
|
{:else}
|
|
MyAnimeList Login
|
|
{/if}
|
|
</button>
|
|
{/if}
|
|
</li>
|
|
<li>
|
|
{#if !isSimklLoggedIn}
|
|
<button
|
|
disabled={loggingIn.includes("simkl")}
|
|
on:click={loginToSimkl}
|
|
>
|
|
{#if loggingIn.includes("simkl")}
|
|
<span
|
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
|
></span
|
|
>Checking Simkl
|
|
{:else}
|
|
Simkl Login
|
|
{/if}
|
|
</button>
|
|
{/if}
|
|
</li>
|
|
</ul>
|
|
<div class="flex justify-center min-[950px]:hidden">
|
|
<Search />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|