Files
DLE/frontend/src/App.vue

205 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
Copyright (c) 2024-2025 Тарабанов Александр Викторович
All rights reserved.
This software is proprietary and confidential.
Unauthorized copying, modification, or distribution is prohibited.
For licensing inquiries: info@hb3-accelerator.com
Website: https://hb3-accelerator.com
GitHub: https://github.com/HB3-ACCELERATOR
-->
<template>
<div id="app">
<div v-if="isLoading" class="loading-overlay">
<div class="loading-spinner" />
</div>
<RouterView v-slot="{ Component }">
<component
:is="Component"
:isAuthenticated="auth.isAuthenticated.value"
:identities="auth.identities.value"
:tokenBalances="tokenBalances"
:isLoadingTokens="isLoadingTokens"
@auth-action-completed="handleAuthActionCompleted"
/>
</RouterView>
</div>
</template>
<script setup>
import { ref, watch, onMounted, computed, onUnmounted } from 'vue';
import { RouterView } from 'vue-router';
import { useAuth, provideAuth } from './composables/useAuth';
import { fetchTokenBalances } from './services/tokens';
import eventBus from './utils/eventBus';
// Импорт стилей
import './assets/styles/variables.css';
import './assets/styles/base.css';
import './assets/styles/layout.css';
import './assets/styles/global.css';
// Состояние загрузки
const isLoading = ref(false);
// Использование composable для аутентификации
const auth = useAuth();
// --- Логика загрузки баланса токенов ---
const tokenBalances = ref({});
const isLoadingTokens = ref(false);
const identities = computed(() => auth.identities.value);
const hasIdentityType = (type) => {
if (!identities.value) return false;
return identities.value.some((identity) => identity.provider === type);
};
const getIdentityValue = (type) => {
if (!identities.value) return null;
const identity = identities.value.find((identity) => identity.provider === type);
return identity ? identity.provider_id : null;
};
const refreshTokenBalances = async () => {
if (!hasIdentityType('wallet') || !auth.isAuthenticated.value) {
tokenBalances.value = {}; // Очищаем, если нет кошелька или не авторизован
return;
}
isLoadingTokens.value = true;
try {
const walletAddress = getIdentityValue('wallet');
// console.log('[App] Обновление балансов для адреса:', walletAddress);
const balances = await fetchTokenBalances(walletAddress);
// console.log('[App] Полученные балансы:', balances);
tokenBalances.value = balances || {};
} catch (error) {
// console.error('[App] Ошибка при получении балансов:', error);
tokenBalances.value = {};
} finally {
isLoadingTokens.value = false;
}
};
// Следим за изменениями в идентификаторах
watch(identities, (newIdentities, oldIdentities) => {
if (auth.isAuthenticated.value) {
const newWalletId = getIdentityValue('wallet');
const oldWalletIdentity = oldIdentities ? oldIdentities.find(id => id.provider === 'wallet') : null;
const oldWalletId = oldWalletIdentity ? oldWalletIdentity.provider_id : null;
if (newWalletId !== oldWalletId) {
// console.log('[App] Обнаружено изменение идентификатора кошелька, обновляем балансы');
refreshTokenBalances();
} else if (hasIdentityType('wallet') && Object.keys(tokenBalances.value).length === 0 && !isLoadingTokens.value) {
// Если кошелек есть, но баланс пустой и не грузится - пробуем загрузить
// console.log('[App] Кошелек есть, но баланс пуст, пытаемся загрузить.');
refreshTokenBalances();
}
}
}, { deep: true });
// Мониторинг изменений состояния аутентификации
watch(auth.isAuthenticated, (isAuth) => {
// console.log('[App] Состояние аутентификации изменилось:', isAuth);
if (isAuth) {
// Убираем задержку, полагаемся на watch(identities) или прямо вызываем
// setTimeout(refreshTokenBalances, 500);
refreshTokenBalances(); // Вызываем сразу, если нужно обновить при смене auth
} else {
// Очищаем баланс при выходе
tokenBalances.value = {};
}
});
// --- Возвращаем и улучшаем функцию-обработчик ---
const handleAuthActionCompleted = async () => {
// console.log('[App] Auth action completed, triggering updates...');
isLoading.value = true; // Показываем индикатор загрузки
try {
// 1. Проверяем аутентификацию (обновит identities и isAuthenticated)
await auth.checkAuth();
// console.log('[App] auth.checkAuth() completed. isAuthenticated:', auth.isAuthenticated.value);
// 2. Обновляем баланс (использует обновленные identities)
await refreshTokenBalances();
// console.log('[App] refreshTokenBalances() completed.');
// 3. Явно оповещаем компоненты об изменении состояния авторизации
// Передаем актуальное состояние из useAuth
eventBus.emit('auth-state-changed', {
isAuthenticated: auth.isAuthenticated.value,
authType: auth.authType.value, // Предполагаем, что authType есть в useAuth
userId: auth.userId.value, // Предполагаем, что userId есть в useAuth
fromApp: true // Флаг, что событие от App.vue
});
// console.log('[App] auth-state-changed event emitted.');
} catch (error) {
// console.error("[App] Error during auth action handling:", error);
} finally {
isLoading.value = false; // Скрываем индикатор загрузки
}
};
// Первичная загрузка баланса при монтировании, если пользователь уже авторизован
onMounted(() => {
if (auth.isAuthenticated.value) {
refreshTokenBalances();
}
// Подписываемся на событие изменения настроек аутентификации
const unsubscribe = eventBus.on('auth-settings-saved', () => {
// console.log('[App] Получено событие сохранения настроек аутентификации, обновляем балансы');
if (auth.isAuthenticated.value) {
refreshTokenBalances();
}
});
// Отписываемся при размонтировании компонента
onUnmounted(() => {
if (unsubscribe) {
unsubscribe();
}
});
});
provideAuth();
</script>
<style>
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 5px solid var(--color-grey-light);
border-top: 5px solid var(--color-primary);
border-radius: 50%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>