import preferences from '@ohos.data.preferences'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { WidgetSize, WidgetTheme, WidgetConfig } from './WidgetTypes'; import { ObjectUtils } from './ObjectUtils'; const TAG = 'WidgetConfigManager'; const CONFIG_PREFERENCES_NAME = 'widget_config_prefs'; /** * 卡片个性化配置接口 */ export interface WidgetPersonalConfig { // 显示配置 showProgress: boolean; showCover: boolean; showAlbum: boolean; showTime: boolean; // 主题配置 theme: WidgetTheme; backgroundColor: string; textColor: string; accentColor: string; // 布局配置 buttonSize: 'small' | 'medium' | 'large'; fontSize: 'small' | 'medium' | 'large'; borderRadius: number; // 行为配置 autoUpdate: boolean; updateInterval: number; clickBehavior: 'play_pause' | 'open_app' | 'open_player'; // 高级配置 enableAnimations: boolean; enableHapticFeedback: boolean; enableShadow: boolean; } /** * 用户偏好设置接口 */ export interface UserPreferences { // 全局偏好 defaultTheme: WidgetTheme; defaultSize: WidgetSize; // 同步设置 syncWithMainApp: boolean; syncThemeColor: boolean; // 性能设置 enableCache: boolean; cacheExpiry: number; // 隐私设置 showSongInfo: boolean; showArtistInfo: boolean; showAlbumCover: boolean; } /** * 卡片配置管理器 * 负责卡片个性化设置和用户偏好管理 * 需求: 5.4, 6.3 */ export class WidgetConfigManager { private static instance: WidgetConfigManager; private preferencesStore: preferences.Preferences | null = null; private configCache: Map = new Map(); private userPreferences: UserPreferences | null = null; /** * 获取单例实例 */ public static getInstance(): WidgetConfigManager { if (!WidgetConfigManager.instance) { WidgetConfigManager.instance = new WidgetConfigManager(); } return WidgetConfigManager.instance; } private constructor() { this.initPreferences(); hilog.info(0x0000, TAG, 'WidgetConfigManager initialized'); } /** * 初始化配置存储 */ private async initPreferences(): Promise { try { this.preferencesStore = await preferences.getPreferences(getContext(), CONFIG_PREFERENCES_NAME); await this.loadUserPreferences(); hilog.info(0x0000, TAG, 'Config preferences initialized successfully'); } catch (error) { hilog.error(0x0000, TAG, `Failed to initialize config preferences: ${error}`); } } /** * 获取卡片个性化配置 * @param formId 卡片ID * @param size 卡片尺寸 * @returns 个性化配置 */ public async getWidgetConfig(formId: string, size: WidgetSize): Promise { // 先从缓存获取 const cacheKey = `${formId}_${size}`; if (this.configCache.has(cacheKey)) { return this.configCache.get(cacheKey)!; } try { if (!this.preferencesStore) { await this.initPreferences(); } const configKey = `config_${formId}`; const configStr = await this.preferencesStore?.get(configKey, '') as string; let config: WidgetPersonalConfig; if (configStr) { config = JSON.parse(configStr) as WidgetPersonalConfig; } else { config = this.getDefaultConfig(size); } // 应用主题色彩同步 if (this.userPreferences?.syncThemeColor) { config = await this.syncThemeColors(config); } // 缓存配置 this.configCache.set(cacheKey, config); hilog.info(0x0000, TAG, `Widget config loaded for form: ${formId}`); return config; } catch (error) { hilog.error(0x0000, TAG, `Failed to get widget config: ${error}`); return this.getDefaultConfig(size); } } /** * 保存卡片个性化配置 * @param formId 卡片ID * @param size 卡片尺寸 * @param config 配置对象 */ public async saveWidgetConfig(formId: string, size: WidgetSize, config: WidgetPersonalConfig): Promise { try { if (!this.preferencesStore) { await this.initPreferences(); } const configKey = `config_${formId}`; await this.preferencesStore?.put(configKey, JSON.stringify(config)); await this.preferencesStore?.flush(); // 更新缓存 const cacheKey = `${formId}_${size}`; this.configCache.set(cacheKey, config); hilog.info(0x0000, TAG, `Widget config saved for form: ${formId}`); } catch (error) { hilog.error(0x0000, TAG, `Failed to save widget config: ${error}`); } } /** * 获取用户偏好设置 */ public async getUserPreferences(): Promise { if (this.userPreferences) { return this.userPreferences; } await this.loadUserPreferences(); return this.userPreferences || this.getDefaultUserPreferences(); } /** * 保存用户偏好设置 * @param preferences 用户偏好 */ public async saveUserPreferences(preferences: UserPreferences): Promise { try { if (!this.preferencesStore) { await this.initPreferences(); } await this.preferencesStore?.put('user_preferences', JSON.stringify(preferences)); await this.preferencesStore?.flush(); this.userPreferences = preferences; hilog.info(0x0000, TAG, 'User preferences saved successfully'); } catch (error) { hilog.error(0x0000, TAG, `Failed to save user preferences: ${error}`); } } /** * 同步主题色彩 * @param config 当前配置 * @returns 同步后的配置 */ public async syncThemeColors(config: WidgetPersonalConfig): Promise { try { // 从主应用获取主题色彩 const mainAppTheme = await this.getMainAppTheme(); if (mainAppTheme) { const updatedConfig = ObjectUtils.cloneWidgetConfig(config); updatedConfig.theme = mainAppTheme.theme; updatedConfig.backgroundColor = mainAppTheme.backgroundColor; updatedConfig.textColor = mainAppTheme.textColor; updatedConfig.accentColor = mainAppTheme.accentColor; return updatedConfig; } } catch (error) { hilog.error(0x0000, TAG, `Failed to sync theme colors: ${error}`); } return config; } /** * 重置卡片配置为默认值 * @param formId 卡片ID * @param size 卡片尺寸 */ public async resetWidgetConfig(formId: string, size: WidgetSize): Promise { const defaultConfig = this.getDefaultConfig(size); await this.saveWidgetConfig(formId, size, defaultConfig); hilog.info(0x0000, TAG, `Widget config reset to default for form: ${formId}`); } /** * 批量更新所有卡片配置 * @param updateFn 更新函数 */ public async updateAllWidgetConfigs(updateFn: (config: WidgetPersonalConfig) => WidgetPersonalConfig): Promise { try { if (!this.preferencesStore) { await this.initPreferences(); } const allKeys = await this.preferencesStore?.getAll(); const allKeysRecord: Record = allKeys as Record || {}; const configKeys = Object.keys(allKeysRecord).filter(key => key.startsWith('config_')); for (let i = 0; i < configKeys.length; i++) { const key = configKeys[i]; const configStr = allKeysRecord[key] as string; if (configStr) { const config = JSON.parse(configStr) as WidgetPersonalConfig; const updatedConfig = updateFn(config); await this.preferencesStore?.put(key, JSON.stringify(updatedConfig)); } } await this.preferencesStore?.flush(); // 清除缓存以强制重新加载 this.configCache.clear(); hilog.info(0x0000, TAG, `Updated ${configKeys.length} widget configs`); } catch (error) { hilog.error(0x0000, TAG, `Failed to update all widget configs: ${error}`); } } /** * 删除卡片配置 * @param formId 卡片ID */ public async removeWidgetConfig(formId: string): Promise { try { if (!this.preferencesStore) { await this.initPreferences(); } const configKey = `config_${formId}`; await this.preferencesStore?.delete(configKey); await this.preferencesStore?.flush(); // 清除相关缓存 const keysToRemove: string[] = []; const cacheKeys = Array.from(this.configCache.keys()); for (let i = 0; i < cacheKeys.length; i++) { const key = cacheKeys[i]; if (key.startsWith(formId)) { keysToRemove.push(key); } } for (let i = 0; i < keysToRemove.length; i++) { this.configCache.delete(keysToRemove[i]); } hilog.info(0x0000, TAG, `Widget config removed for form: ${formId}`); } catch (error) { hilog.error(0x0000, TAG, `Failed to remove widget config: ${error}`); } } /** * 获取默认配置 */ private getDefaultConfig(size: WidgetSize): WidgetPersonalConfig { const baseConfig: WidgetPersonalConfig = { // 显示配置 showProgress: true, showCover: true, showAlbum: true, showTime: true, // 主题配置 theme: WidgetTheme.AUTO, backgroundColor: '#FFFFFF', textColor: '#E6000000', accentColor: '#FF007DFF', // 布局配置 buttonSize: 'medium', fontSize: 'medium', borderRadius: 12, // 行为配置 autoUpdate: true, updateInterval: 1000, clickBehavior: 'play_pause', // 高级配置 enableAnimations: true, enableHapticFeedback: true, enableShadow: true }; // 根据尺寸调整默认配置 if (size === WidgetSize.SMALL) { const smallConfig = ObjectUtils.cloneWidgetConfig(baseConfig); smallConfig.showProgress = false; smallConfig.showCover = false; smallConfig.showAlbum = false; smallConfig.showTime = false; smallConfig.buttonSize = 'small'; smallConfig.fontSize = 'small'; smallConfig.borderRadius = 8; return smallConfig; } else if (size === WidgetSize.MEDIUM) { const mediumConfig = ObjectUtils.cloneWidgetConfig(baseConfig); mediumConfig.showCover = false; mediumConfig.buttonSize = 'medium'; mediumConfig.fontSize = 'medium'; mediumConfig.borderRadius = 12; return mediumConfig; } else if (size === WidgetSize.LARGE) { const largeConfig = ObjectUtils.cloneWidgetConfig(baseConfig); largeConfig.buttonSize = 'large'; largeConfig.fontSize = 'large'; largeConfig.borderRadius = 16; return largeConfig; } else { return baseConfig; } } /** * 获取默认用户偏好 */ private getDefaultUserPreferences(): UserPreferences { return { // 全局偏好 defaultTheme: WidgetTheme.AUTO, defaultSize: WidgetSize.MEDIUM, // 同步设置 syncWithMainApp: true, syncThemeColor: true, // 性能设置 enableCache: true, cacheExpiry: 30000, // 隐私设置 showSongInfo: true, showArtistInfo: true, showAlbumCover: true }; } /** * 加载用户偏好设置 */ private async loadUserPreferences(): Promise { try { if (!this.preferencesStore) { return; } const prefsStr = await this.preferencesStore.get('user_preferences', '') as string; if (prefsStr) { this.userPreferences = JSON.parse(prefsStr) as UserPreferences; } else { this.userPreferences = this.getDefaultUserPreferences(); } } catch (error) { hilog.error(0x0000, TAG, `Failed to load user preferences: ${error}`); this.userPreferences = this.getDefaultUserPreferences(); } } /** * 从主应用获取主题信息 */ private async getMainAppTheme(): Promise { try { // 这里应该从主应用的主题管理器获取主题信息 // 暂时返回默认主题 return { theme: WidgetTheme.AUTO, backgroundColor: '#FFFFFF', textColor: '#E6000000', accentColor: '#FF007DFF' }; } catch (error) { hilog.error(0x0000, TAG, `Failed to get main app theme: ${error}`); return null; } } } /** * 主应用主题接口 */ interface MainAppTheme { theme: WidgetTheme; backgroundColor: string; textColor: string; accentColor: string; }