diff --git a/src/components/Account/AccountLogin.tsx b/src/components/Account/AccountLogin.tsx index a90bfe5d..7d12d82a 100644 --- a/src/components/Account/AccountLogin.tsx +++ b/src/components/Account/AccountLogin.tsx @@ -1,7 +1,8 @@ import { type JSX, mergeProps } from "solid-js"; +import { produce } from "solid-js/store"; import "./AccountLogin.scss"; -import { produce } from "solid-js/store"; +import { YANDEX_TOKEN_DEFAULT_LIFETIME } from "../../config/auth"; import { t } from "../../localization/localizationProvider"; import { setAccount } from "../../stores/account"; import { votStorage } from "../../utils/storage"; @@ -15,8 +16,6 @@ export type AccountLoginProps = { onClickLogin?: () => void; }; -const TOKEN_LIFETIME = 31_534_180_000; // 1 year in milliseconds - export function AccountLogin(props: AccountLoginProps): JSX.Element { const finalProps = mergeProps( { disableExternalLogin: votStorage.isSupportOnlyLS }, @@ -50,12 +49,11 @@ export function AccountLogin(props: AccountLoginProps): JSX.Element { const data = value ? { token: value, - expires: Date.now() + TOKEN_LIFETIME, + expires: Date.now() + YANDEX_TOKEN_DEFAULT_LIFETIME, } : {}; const isLoggedIn = Boolean(value); - // TODO: add get account info via token and set username and avatarId await votStorage.set("account", { ...data }); setAccount( produce((state) => { diff --git a/src/components/Account/AccountRefreshButton.tsx b/src/components/Account/AccountRefreshButton.tsx index d0c2949e..4715ddcf 100644 --- a/src/components/Account/AccountRefreshButton.tsx +++ b/src/components/Account/AccountRefreshButton.tsx @@ -1,7 +1,7 @@ import type { JSX } from "solid-js"; import { updateAccountInfo } from "../../core/auth/yandex"; import { t } from "../../localization/localizationProvider"; -import { updateAccountFromStorage } from "../../stores/account"; +import { account, updateAccountFromStorage } from "../../stores/account"; import { IconButton } from "../Button/IconButton"; import { RefreshIcon } from "../Icons/RefreshIcon"; @@ -16,7 +16,12 @@ export function AccountRefreshButton( { + if (account.isRefreshing) { + return; + } + try { await updateAccountInfo(); } catch { diff --git a/src/config/auth.ts b/src/config/auth.ts index 72201ddc..81dc0c5a 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -6,3 +6,4 @@ export const YANDEX_AUTH_TOKEN_URL = `${YANDEX_AUTH_ORIGIN}/token`; export const YANDEX_AUTH_AVATAR_BASE = "https://avatars.mds.yandex.net/get-yapic"; export const YANDEX_USER_INFO_URL = "https://login.yandex.ru/info"; +export const YANDEX_TOKEN_DEFAULT_LIFETIME = 31_534_180_000; // 1 year in milliseconds diff --git a/src/core/auth/yandex.ts b/src/core/auth/yandex.ts index 9d05da42..d7fbd7a6 100644 --- a/src/core/auth/yandex.ts +++ b/src/core/auth/yandex.ts @@ -7,7 +7,7 @@ import { YANDEX_AUTH_URL, YANDEX_USER_INFO_URL, } from "../../config/auth"; -import { updateAccount } from "../../stores/account"; +import { setAccount, updateAccount } from "../../stores/account"; import type { AuthMessageData } from "../../types/core/auth/message"; import type { AuthError, @@ -105,6 +105,7 @@ export async function updateAccountInfo() { let username: string; let avatarId: string; try { + setAccount("isRefreshing", true); const userInfo = await getUserInfo(account.token); username = userInfo.login; avatarId = userInfo.default_avatar_id; @@ -120,6 +121,8 @@ export async function updateAccountInfo() { }); } catch (err) { console.error("[VOT] Failed to fetch user info:", err); + } finally { + setAccount("isRefreshing", false); } } diff --git a/src/stores/account.ts b/src/stores/account.ts index 203ac3d1..44069462 100644 --- a/src/stores/account.ts +++ b/src/stores/account.ts @@ -4,6 +4,7 @@ import { hasValidAccountToken } from "../utils/account"; import { votStorage } from "../utils/storage"; export type AccountStore = { + isRefreshing: boolean; isLoggedIn: boolean; username?: string; avatarId?: string; @@ -13,6 +14,7 @@ export type AccountStore = { function createInitialState(): AccountStore { return { + isRefreshing: false, isLoggedIn: false, username: undefined, avatarId: undefined,