modified: .gitignore
This commit is contained in:
45
resources/js/Composables/useGlobalLoading.js
Normal file
45
resources/js/Composables/useGlobalLoading.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import {computed, ref} from "vue";
|
||||
|
||||
const pending = ref(0)
|
||||
const visible = ref(false)
|
||||
let showTimer = null
|
||||
|
||||
const SHOW_DELAY_MS = 3000
|
||||
|
||||
const scheduleShow = () => {
|
||||
if (visible.value || showTimer) return
|
||||
|
||||
showTimer = setTimeout(() => {
|
||||
showTimer = null
|
||||
if (pending.value > 0) {
|
||||
visible.value = true
|
||||
}
|
||||
}, SHOW_DELAY_MS)
|
||||
}
|
||||
|
||||
const cancelScheduledShow = () => {
|
||||
if (!showTimer) return
|
||||
clearTimeout(showTimer)
|
||||
showTimer = null
|
||||
}
|
||||
|
||||
export const startGlobalLoading = () => {
|
||||
pending.value += 1
|
||||
scheduleShow()
|
||||
}
|
||||
|
||||
export const stopGlobalLoading = () => {
|
||||
pending.value = Math.max(0, pending.value - 1)
|
||||
|
||||
if (pending.value === 0) {
|
||||
cancelScheduledShow()
|
||||
visible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
export const useGlobalLoading = () => {
|
||||
return {
|
||||
isGlobalLoading: computed(() => visible.value),
|
||||
pendingCount: computed(() => pending.value),
|
||||
}
|
||||
}
|
||||
102
resources/js/Composables/useServerTime.js
Normal file
102
resources/js/Composables/useServerTime.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import { useEventSource } from '@vueuse/core'
|
||||
import { usePage } from '@inertiajs/vue3'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
export function useServerTime() {
|
||||
const page = usePage()
|
||||
const url = page.props.config?.timeEventSourceUrl
|
||||
|
||||
// Реактивные состояния
|
||||
const serverTime = ref(null)
|
||||
const lastRawData = ref(null)
|
||||
const error = ref(null)
|
||||
const isConnected = ref(false)
|
||||
|
||||
if (!url) {
|
||||
console.warn('[useServerTime] TIME_EVENT_SOURCE_URL not configured')
|
||||
return {
|
||||
serverTime,
|
||||
lastRawData,
|
||||
error,
|
||||
isConnected,
|
||||
status: 'CONFIG_ERROR'
|
||||
}
|
||||
}
|
||||
|
||||
// Подключаемся к EventSource, слушаем кастомное событие "ServerTimeEvent"
|
||||
const { status, data, eventSource } = useEventSource(url, 'ServerTimeEvent', {
|
||||
immediate: true,
|
||||
onError: (e) => {
|
||||
error.value = e
|
||||
isConnected.value = false
|
||||
console.error('[useServerTime] Connection error:', e)
|
||||
},
|
||||
onOpen: () => {
|
||||
isConnected.value = true
|
||||
error.value = null
|
||||
console.log('[useServerTime] Connected')
|
||||
},
|
||||
onClose: () => {
|
||||
isConnected.value = false
|
||||
console.log('[useServerTime] Disconnected')
|
||||
}
|
||||
})
|
||||
|
||||
// Парсим данные при получении
|
||||
if (data) {
|
||||
watch(() => data.value, (newData) => {
|
||||
if (!newData) return
|
||||
|
||||
lastRawData.value = newData
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(newData)
|
||||
|
||||
if (parsed.time) {
|
||||
// Создаём дату из ISO-строки
|
||||
serverTime.value = new Date(parsed.time)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[useServerTime] Failed to parse event:', newData, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Удобные вычисляемые свойства
|
||||
const formattedTime = computed(() => {
|
||||
if (!serverTime.value) return null
|
||||
return serverTime.value.toLocaleString('ru-RU', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
timeZoneName: 'short'
|
||||
})
|
||||
})
|
||||
|
||||
const timeDiff = computed(() => {
|
||||
if (!serverTime.value) return null
|
||||
return Date.now() - serverTime.value.getTime() // задержка в мс
|
||||
})
|
||||
|
||||
// Функция для принудительного переподключения
|
||||
const reconnect = () => {
|
||||
if (eventSource.value?.readyState === EventSource.OPEN) {
|
||||
eventSource.value.close()
|
||||
}
|
||||
// useEventSource автоматически переподключится при изменении URL или через retry-логику
|
||||
}
|
||||
|
||||
return {
|
||||
serverTime, // Date | null
|
||||
formattedTime, // отформатированная строка "01.04.2026, 16:59:49"
|
||||
lastRawData, // сырые данные для отладки
|
||||
error, // ошибка подключения
|
||||
isConnected, // статус соединения
|
||||
status, // 'CONNECTING' | 'OPEN' | 'CLOSED'
|
||||
timeDiff, // задержка в мс (для мониторинга)
|
||||
reconnect // метод переподключения
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user