import { defineStore } from 'pinia' import { ref, computed } from 'vue' import type { VideoItem, VideoListResponse, ThemeSettings, WidgetState, WindowState } from '../types' const defaultTheme: ThemeSettings = { primaryColor: '#007AFF', backgroundColor: 'rgba(30, 30, 30, 0.7)', glassOpacity: 0.7, blurAmount: 20 } function mergeTheme(savedTheme: Partial | undefined): ThemeSettings { if (!savedTheme) return { ...defaultTheme } return { primaryColor: savedTheme.primaryColor ?? defaultTheme.primaryColor, backgroundColor: savedTheme.backgroundColor ?? defaultTheme.backgroundColor, glassOpacity: savedTheme.glassOpacity ?? defaultTheme.glassOpacity, blurAmount: savedTheme.blurAmount ?? defaultTheme.blurAmount } } export const useSettingsStore = defineStore('settings', () => { const currentVideo = ref(null) const videoList = ref([]) const theme = ref({ ...defaultTheme }) const widgets = ref([]) const windows = ref([]) const isMobile = ref(false) function initTheme() { theme.value = mergeTheme(theme.value) } const isWindowOpen = computed(() => { return (id: string) => windows.value.find(w => w.id === id)?.isOpen ?? false }) const getWindowState = computed(() => { return (id: string) => windows.value.find(w => w.id === id) }) async function fetchVideoList() { try { const response = await fetch('/api/fs/list', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ path: '/mp4', password: '', page: 1, per_page: 0, refresh: false }) }) const data: VideoListResponse = await response.json() if (data.code === 200) { videoList.value = data.data.content.filter(item => item.name.endsWith('.mp4')) if (!currentVideo.value && videoList.value.length > 0) { currentVideo.value = videoList.value[0] } } } catch (error) { console.error('Failed to fetch video list:', error) } } function setCurrentVideo(video: VideoItem) { currentVideo.value = video } function updateTheme(newTheme: Partial) { theme.value = { ...theme.value, ...newTheme } } function resetTheme() { theme.value = { ...defaultTheme } } function updateWidgetPosition(id: string, position: { x: number; y: number }) { const widget = widgets.value.find(w => w.id === id) if (widget) { widget.position = position } else { widgets.value.push({ id, position, order: widgets.value.length }) } } function updateWidgetOrder(id: string, newOrder: number) { const widget = widgets.value.find(w => w.id === id) if (widget) { widget.order = newOrder } } function openWindow(id: string, position?: { x: number; y: number }, size?: { width: number; height: number }) { const existingWindow = windows.value.find(w => w.id === id) if (existingWindow) { existingWindow.isOpen = true existingWindow.zIndex = Math.max(...windows.value.map(w => w.zIndex), 0) + 1 } else { const defaultWidth = size?.width ?? 800 const defaultHeight = size?.height ?? 600 const defaultX = (window.innerWidth - defaultWidth) / 2 const defaultY = (window.innerHeight - defaultHeight) / 2 windows.value.push({ id, isOpen: true, position: position ?? { x: Math.max(20, defaultX), y: Math.max(20, defaultY) }, size: size ?? { width: defaultWidth, height: defaultHeight }, zIndex: Math.max(...windows.value.map(w => w.zIndex), 0) + 1 }) } } function closeWindow(id: string) { const window = windows.value.find(w => w.id === id) if (window) { window.isOpen = false } } function updateWindowPosition(id: string, position: { x: number; y: number }) { const window = windows.value.find(w => w.id === id) if (window) { window.position = position } } function updateWindowSize(id: string, size: { width: number; height: number }) { const window = windows.value.find(w => w.id === id) if (window) { window.size = size } } function bringWindowToFront(id: string) { const window = windows.value.find(w => w.id === id) if (window) { window.zIndex = Math.max(...windows.value.map(w => w.zIndex), 0) + 1 } } function setMobile(value: boolean) { isMobile.value = value } function initWidgets(widgetIds: string[]) { const existingIds = widgets.value.map(w => w.id) widgetIds.forEach((id, index) => { if (!existingIds.includes(id)) { widgets.value.push({ id, position: { x: -1, y: -1 }, order: index }) } }) } function updateWidgetDefaultPosition(id: string, width: number, height: number) { const widget = widgets.value.find(w => w.id === id) if (widget) { const screenWidth = window.innerWidth const screenHeight = window.innerHeight const positions: Record = { calendar: { x: screenWidth - 340, y: 20 }, taoxin: { x: screenWidth - 320, y: screenHeight - 380 }, cafe: { x: screenWidth - 660, y: 20 } } if (positions[id]) { const newPos = positions[id] const isDefaultPosition = widget.position.x === 20 && widget.position.y < 500 const isOutOfBounds = widget.position.x < 0 || widget.position.x > screenWidth - 100 || widget.position.y < 0 || widget.position.y > screenHeight - 100 if (isDefaultPosition || isOutOfBounds) { widget.position = newPos } } } } return { currentVideo, videoList, theme, widgets, windows, isMobile, isWindowOpen, getWindowState, fetchVideoList, setCurrentVideo, updateTheme, resetTheme, updateWidgetPosition, updateWidgetOrder, openWindow, closeWindow, updateWindowPosition, updateWindowSize, bringWindowToFront, setMobile, initWidgets, initTheme, updateWidgetDefaultPosition } }, { persist: { key: 'wufangzhen-settings', storage: typeof window !== 'undefined' ? localStorage : undefined, paths: ['currentVideo', 'theme', 'widgets', 'windows'] } })