import TitleBar from '../view/TitleBar' import { promptAction, router } from '@kit.ArkUI' import { CommonConstants } from '../common/constants/CommonConstants' import { EventConstants } from '../common/constants/EventConstants' import { AppUtil, DeviceUtil, DisplayUtil, FileUtil, LogUtil, MD5, PreferencesUtil, ToastUtil } from '@pura/harmony-utils' import { CustomContentDialog } from '@kit.ArkUI' import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; import common from '@ohos.app.ability.common'; import { photoAccessHelper } from '@kit.MediaLibraryKit' import { fileIo, fileUri } from '@kit.CoreFileKit' import { BusinessError, emitter } from '@kit.BasicServicesKit' import { BreakpointTypeEnum } from '../common/util/BreakpointSystem' import { Utility } from '../common/util/Utility' import { HSBColorPicker } from '@keke/color-picker' import { DialogHelper } from '@pura/harmony-dialog' import { bundleManager } from '@kit.AbilityKit' import { hilog } from '@kit.PerformanceAnalysisKit' import { SelectItem } from './SelectItem' import { FastForwardSecondInterface } from './FastForwardSecondInterface' import { ButtonFancyModifier, ShadowModifier, SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil' import { CustomizeICON, Icon } from '../view/CustomizeICON' import { appInfoManager } from '@kit.StoreKit' import { clearWebDavCacheByAccount, clearWebDavCaches } from '../common/network/RemoteSongCache'; import { RemoteDriveManager } from '../common/util/RemoteDriveManager'; import { LogCollector } from '../common/util/LogCollector'; import { Uploader, UploadConfig } from '../common/network/Uploader'; import { UpTokenUtil } from '../common/util/UpTokenUtil'; import { ServerLogUtil } from '../common/util/ServerLogUtil'; import { audio } from '@kit.AudioKit' @Preview // @Entry @Component export struct SettingPage { @State autoHideTitle: boolean = true //滚动自动隐藏标题栏 @State isNoJumpToHome: boolean = false //网盘播放不跳转首页 @State iconCurrentID: string = 'default';//图标的id @State iconArray: Array = [] @State webdavUploadDuplicateAction: string = 'skip' // WebDAV上传重复文件处理方式 @State webdavUploadAutoClear: boolean = false // WebDAV上传完成后自动清理队列 @State webdavUploadAllowMobile: boolean = false // WebDAV是否允许移动网络上传 @State webdavUploadRetryCount: number = 3 // WebDAV上传失败自动重试次数 @StorageProp('isLandscape') isLandscape: boolean = false; @State isCustomizeICONSheet: boolean = false //自定义背景界面 @StorageProp('topSafeHeight') topSafeHeight: number = 0; @State isCopyFileToDownLoad: boolean = false static readonly IS_COPYFILE_TO_DOWNLOAD: string = 'isCopyFileToDownLoad'; static readonly WEBDAV_UPLOAD_DUPLICATE_ACTION: string = 'webdavUploadDuplicateAction'; static readonly WEBDAV_UPLOAD_AUTO_CLEAR: string = 'webdavUploadAutoClear'; static readonly WEBDAV_UPLOAD_ALLOW_MOBILE: string = 'webdavUploadAllowMobile'; static readonly WEBDAV_UPLOAD_RETRY_COUNT: string = 'webdavUploadRetryCount'; @State fastForwardSeconds: string = '10' @State isShowBackFast: boolean = true//快进快退按钮 @State isClearingCache: boolean = false @Consume isShowDrawer: boolean; @Consume offsetX: number; @Consume mType: number; static readonly THEME_MODE: string = 'themeMode'; static readonly SORT_TYPE: string = 'musicSortType'; static readonly IS_BGPLAY_OPEN: string = 'isBgPlayOpen'; static readonly IS_AUTO_RATATE: string = 'isAutoRatate'; static readonly iS_MEMORY_PLAY: string = 'isMemoryPlay'; static readonly IS_MIDIACODEC_OPEN: string = 'isMediacodec'; static readonly iS_MUSIC_MEMORY_PLAY: string = 'isMusicMemoryPlay'; static readonly iS_MUSIC_BG_COVER: string = 'isMusicBGCover'; static readonly iS_SAVE_PLAY_MODE: string = 'isSavePlayMode'; static readonly IS_COVER_RECTANGLE: string = 'isCoverRectangle'; //封面圆形或者方形 static readonly IS_SHOW_SIMI: string = 'isShowSimi'; static readonly IS_SHOW_FAV: string = 'isShowFAV'; static readonly IS_SHOW_HISTORY: string = 'isShowHistory'; static readonly IS_CUSTOMIZE_BG: string = 'is_customize_bg'; static readonly IS_GRID_MUSIC: string = 'is_grid_music'; static readonly IS_CUSTOMIZE_BG_PATH: string = 'is_customize_bg_path'; static readonly IS_SCROLL_HIDE: string = 'isAutoScrollHide'; static readonly IS_SAMETIME_PLAY: string = 'isSameTimePlay'; static readonly CUSTOMIZE_BG_BLUR: string = 'customize_bg_blur'; static readonly BG_BRIGHTNESS: string = 'bg_brightness'; static readonly IS_SHOW_ALLBAR: string = 'IS_SHOW_ALLBAR'; static readonly IS_SHOW_TITLTBAR: string = 'IS_SHOW_TITLTBAR'; static readonly IS_SHOW_PLAYPAGE_BACK: string = 'IS_SHOW_PLAYPAGE_BACK'; static readonly IS_SHOW_SLLYRIC: string = 'IS_SHOW_SLLYRIC'; static readonly IS_CIRCLE_BTN: string = 'isCircleBtn'; static readonly IS_COVER_TOP: string = 'IS_COVER_TOP'; static readonly IS_SHOW_HEADER: string = 'IS_SHOW_HEADER'; static readonly IS_COVER_TOP_BIG: string = 'IS_COVER_TOP_BIG'; static readonly LOG_UPLOAD_ENABLED: string = 'logUploadEnabled'; static readonly MEITU_UPLOAD_TOKEN_KEY: string = 'meituUploadToken'; static readonly MEITU_UPLOAD_DOMAIN_KEY: string = 'meituUploadDomain'; static readonly MEITU_AK: string = '7msMIyQ9xOjOwqO9JSPl'; static readonly MEITU_SK: string = 'JU8kLByQ1U1Zgkfni95IC9ttvfv5NLC3qO642R1Z'; static readonly MEITU_BUCKET: string = 'makeup-magic'; static readonly MEITU_DOMAIN: string = 'https://makeup-magic.zone1.meitudata.com'; public static THEME_COLOR_KEY: string = 'THEME_COLOR'; public static TWO_FINGER_TYPE: string = 'twoFingerType'; public static LONG_PRESS_SPEED: string = 'longPressSpeed'; public static IS_PLAYLIST_BG_GRASS: string = 'isPlayListBgGrass'; static readonly IS_SWIPE: string = 'isSwipe' static readonly IS_AUTO_HIDE_PROGRESS: string = 'IS_AUTO_HIDE_PROGRESS'; public static OPEN_SKIPSONG_ANIMATE: string = 'openSkipSongAnimate'; @State autoParseMusicName: boolean = false @State idDefaultMediaKu: boolean = false private fastForwardSecond: FastForwardSecondInterface[] = [ { label: '5秒', value: '5' }, { label: '10秒', value: '10' }, { label: '15秒', value: '15' }, { label: '20秒', value: '20' }, { label: '30秒', value: '30' }, { label: '60秒', value: '60' }, { label: '90秒', value: '90' }, ]; public static THEME_COLOR_LIST: Array = [ { name: '玫瑰粉', color: '#FF4081', isVip: false }, { name: '经典蓝', color: '#0A59F7', isVip: false }, { name: '活力黄', color: '#FFC107', isVip: true }, { name: '枫叶红', color: '#F44336', isVip: true }, { name: '幻影紫', color: '#9C27B0', isVip: true }, { name: '翡翠绿', color: '#64BB5C', isVip: true }, { name: '竹青蓝', color: '#00BCD4', isVip: true }, { name: '深空灰', color: '#607D8B', isVip: true }, { name: '橙霞橙', color: '#FF9800', isVip: true }, { name: '湖水蓝', color: '#00BFFF', isVip: true }, { name: '柠檬绿', color: '#C6FF00', isVip: true }, { name: '樱花粉', color: '#FF69B4', isVip: true }, { name: '暮夜蓝', color: '#283593', isVip: true }, { name: '薄荷青', color: '#1DE9B6', isVip: true }, { name: '银沙灰', color: '#B0BEC5', isVip: true }, { name: '自定义', color: '#ffecec', isVip: true } ]; static readonly iS_START_AUTO_PLAY: string = 'isStartAutoPlay'; static readonly iS_MEMORY_LAST_PLAY: string = 'isMemoryLastPlay'; @State showApiDialog: boolean = false @State tempApiUrl: string = '' @State lyricApiUrl: string = PreferencesUtil.getStringSync('LRC_API', '') @State isBgPlayOpen: boolean = true //是否启用后台播放 @State isAutoRatate: boolean = true //是否启用自动横竖屏 @State isMemoryPlay: boolean = true //是否启用记忆播放 @State isMediacodec: boolean = false //是否启用硬件解码 @State isMusicMemoryPlay: boolean = false //是否启用记忆播放 @State isMusicBGCover: boolean = true //播放背景随封面 @State sortType: number = 4 //默认排序方式 @State isStartAutoPlay: boolean = false //启动后自动播放 @State isMemoryLastPlay: boolean = false //是否启用应用退出记忆最后一首的播放进度 @State isShowSimi: boolean = false //是否显示私密音频 @State isShowFAV: boolean = true //是否显示我的收藏 @State isShowHistory: boolean = true //是否显示最近播放 @State isShowPlayPageBack: boolean = false //是否显示播放页返回键 @State isShowPrecious: boolean = false //播控条显示上一首按钮 @State isShowSingleLineLyric: boolean = false //是否显示单行歌词 @State isLogUploadEnabled: boolean = false //日志上传开关 @State isClearingLogs: boolean = false //是否正在清除日志 @State isShowHeader: boolean = true @State isCustomizeBg: boolean = false //自定义背景界面 @State isCustomizeBgSheet: boolean = false //自定义背景界面 @State isShowTitleBar: boolean = true //是否显示分类导航条 @State isShowAllBar: boolean = true //是否显示播放全部条 @State longPressSpeed: number = 3 //长按默认倍数 @State blurValue: number = 0 //背景模糊 @State bgBrightness: number = 0 //背景亮度 @State isGridMusic: boolean = true //是否网格布局 @State isCircleBtn: boolean = false //是否圆形播放按钮 @State twoFingerType: number = 3 //双指放大瘦小Grid或list的大小 @State isScrollHide: boolean = false //是否滚动隐藏 @State isSameTimePlay: boolean = false //是否和其他app同时播放 @State isCoverRectangle: boolean = false @State isSavePlayMode: boolean = true @State volumeSmall: boolean = false @State isCoverTop: boolean = true @State isCoverTopBig: boolean = false//顶部大封面部分手机显示会和播放控制页重叠 @State isSwipe: boolean = false //listItem的左滑开关 @State isPlayListBgGrass: boolean = true//是否播放列表玻璃透明效果 @State is_auto_hide_progress: boolean = false @State openSkipSongAnimate: boolean = true//切歌动画效果 @State isShowFileName: boolean = false//切歌动画效果 @State isLongNameRoLL: boolean = true//长歌名滚动 @State customizeBgPath: string | undefined = ''; context = getContext(this); @State showCoverApiDialog: boolean = false @State tempCoverApiUrl: string = '' @State coverApiUrl: string = PreferencesUtil.getStringSync('COVER_API', '') @State apiDialogType: 'lyric' | 'cover' = 'lyric' @State themeMode: number = 0 // 0: 跟随系统, 1: 浅色, 2: 深色 @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT; @StorageLink('isDarkMode') isDarkMode: boolean = false // 是否启用深色模式 /** 当前断点类型(如大屏/小屏) */ @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD; @State verName: string = '' @StorageProp('themeColor') themeColor: string = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR); @State showColorPicker: boolean = false @State customColor: string = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR); @State isThemeSheet: boolean = false // 主题设置弹窗显示状态 @State colorRows: Array> = chunkArray(SettingPage.THEME_COLOR_LIST, 2); @State colorGroup: string = "group" @StorageProp('topRectHeight') topRectHeight: number = 0; apiDialogController: CustomDialogController = new CustomDialogController({ builder: CustomContentDialog({ primaryTitle: this.apiDialogType === 'lyric' ? '修改歌词API地址' : '修改封面API地址', contentBuilder: () => { this.buildApiDialogContent(); }, buttons: [ { value: '取消', action: () => { this.apiDialogController.close(); } }, { value: '保存', action: () => { if (this.apiDialogType === 'lyric') { this.lyricApiUrl = this.tempApiUrl.trim() PreferencesUtil.put('LRC_API', this.lyricApiUrl) this.getUIContext().getPromptAction().showToast({ message: '保存成功,当前LRC_API:' + this.lyricApiUrl, duration: 2000, showMode: promptAction.ToastShowMode.TOP_MOST, bottom: 85 }) } else { this.coverApiUrl = this.tempApiUrl.trim() PreferencesUtil.put('COVER_API', this.coverApiUrl) this.getUIContext().getPromptAction().showToast({ message: '保存成功,当前COVER_API:' + this.coverApiUrl, duration: 2000, showMode: promptAction.ToastShowMode.TOP_MOST, bottom: 85 }) } this.apiDialogController.close(); } } ] }), autoCancel: true, alignment: DialogAlignment.Center }) @Builder buildApiDialogContent() { Column() { TextInput({ text: this.tempApiUrl, placeholder: this.apiDialogType === 'lyric' ? '请输入歌词API地址' : '请输入封面API地址' }) .onChange((val: string) => { this.tempApiUrl = val }) .width('90%') .height(60) } .width('100%') } // 组件生命周期 aboutToAppear() { // this.geIDD() this.autoHideTitle = PreferencesUtil.getBooleanSync('autoHideTitle', true) this.isShowPrecious = PreferencesUtil.getBooleanSync('isShowPrecious', false) this.isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN, true) this.isAutoRatate = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_RATATE, true) this.isMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_PLAY, true) this.isMediacodec = PreferencesUtil.getBooleanSync(SettingPage.IS_MIDIACODEC_OPEN, false) this.isMusicMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_MEMORY_PLAY, false) this.isMusicBGCover = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_BG_COVER, true) this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4) this.isShowSimi = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SIMI, false) this.isShowFAV = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_FAV, true) this.isShowHistory = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HISTORY, true) this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false) this.customizeBgPath = PreferencesUtil.getStringSync(SettingPage.IS_CUSTOMIZE_BG_PATH, '') this.isGridMusic = PreferencesUtil.getBooleanSync(SettingPage.IS_GRID_MUSIC, false) this.isScrollHide = PreferencesUtil.getBooleanSync(SettingPage.IS_SCROLL_HIDE, false) this.isSameTimePlay = PreferencesUtil.getBooleanSync(SettingPage.IS_SAMETIME_PLAY, false) this.isSavePlayMode = PreferencesUtil.getBooleanSync(SettingPage.iS_SAVE_PLAY_MODE, true) this.blurValue = PreferencesUtil.getNumberSync(SettingPage.CUSTOMIZE_BG_BLUR, 0) this.bgBrightness = PreferencesUtil.getNumberSync(SettingPage.BG_BRIGHTNESS, 0) this.isStartAutoPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_START_AUTO_PLAY, false) this.isMemoryLastPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_LAST_PLAY, false) this.twoFingerType = PreferencesUtil.getNumberSync(SettingPage.TWO_FINGER_TYPE, 2) this.isCircleBtn = PreferencesUtil.getBooleanSync(SettingPage.IS_CIRCLE_BTN, true) this.isCoverTop = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP, true) this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, false) this.isShowAllBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_ALLBAR, true) this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, true) this.isShowSingleLineLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SLLYRIC, false) this.isCoverTopBig = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP_BIG, false) this.longPressSpeed = PreferencesUtil.getNumberSync(SettingPage.LONG_PRESS_SPEED, 3) this.isShowHeader = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HEADER, true) this.isCoverRectangle = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_RECTANGLE, true) this.isPlayListBgGrass = PreferencesUtil.getBooleanSync(SettingPage.IS_PLAYLIST_BG_GRASS, true) this.isSwipe = PreferencesUtil.getBooleanSync(SettingPage.IS_SWIPE, true) this.is_auto_hide_progress = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_HIDE_PROGRESS, false) this.openSkipSongAnimate = PreferencesUtil.getBooleanSync(SettingPage.OPEN_SKIPSONG_ANIMATE, true) this.volumeSmall = PreferencesUtil.getBooleanSync('volumeSmall', false) this.autoParseMusicName = PreferencesUtil.getBooleanSync('autoParseMusicName', true) this.idDefaultMediaKu = PreferencesUtil.getBooleanSync('idDefaultMediaKu', false) this.isShowFileName = PreferencesUtil.getBooleanSync('isShowFileName', false) this.isLongNameRoLL = PreferencesUtil.getBooleanSync('isLongNameRoLL', true) this.isShowBackFast = PreferencesUtil.getBooleanSync('isShowBackFast', false) this.fastForwardSeconds = PreferencesUtil.getStringSync('fastForwardSeconds', '10') this.isCopyFileToDownLoad = PreferencesUtil.getBooleanSync(SettingPage.IS_COPYFILE_TO_DOWNLOAD, false) this.isNoJumpToHome = PreferencesUtil.getBooleanSync('isNoJumpToHome', true) this.webdavUploadDuplicateAction = PreferencesUtil.getStringSync(SettingPage.WEBDAV_UPLOAD_DUPLICATE_ACTION, 'skip') this.webdavUploadAutoClear = PreferencesUtil.getBooleanSync(SettingPage.WEBDAV_UPLOAD_AUTO_CLEAR, false) this.webdavUploadAllowMobile = PreferencesUtil.getBooleanSync(SettingPage.WEBDAV_UPLOAD_ALLOW_MOBILE, false) this.webdavUploadRetryCount = PreferencesUtil.getNumberSync(SettingPage.WEBDAV_UPLOAD_RETRY_COUNT, 3) this.isLogUploadEnabled = PreferencesUtil.getBooleanSync(SettingPage.LOG_UPLOAD_ENABLED, false) if (this.isLogUploadEnabled) { this.ensureMeituUploadHandler(true) } else { this.registerLogUploadDisabled() } // 只用 themeMode 控制主题 this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0) this.applyThemeMode(this.themeMode) let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR); AppStorage.setOrCreate('themeColor', themeColor); this.themeColor = themeColor; this.initIcon() } initIcon(){ this.iconCurrentID = PreferencesUtil.getStringSync('iconCurrentID', 'default') const iconItem:Icon = { iconUrl: 'default', iconId: 'default', enabled: false } this.iconArray.push(iconItem) try { appInfoManager.queryDynamicIcons() .then((queryResult: appInfoManager.DynamicIconInfo[]) => { hilog.info(0, 'TAG', "Succeeded in getting queryResult= " + JSON.stringify(queryResult)); const iconList = JSON.parse(JSON.stringify(queryResult)) as Array; this.iconArray = this.iconArray.concat(iconList) }).catch((error: BusinessError) => { hilog.error(0, 'TAG', "queryDynamicIcons failed, code: " + error.code + ", exception message: " + error.message); }); } catch (error) { hilog.error(0, 'TAG', "queryDynamicIcons exception code: " + error.code + ", exception message: " + error.message); } } // 监听颜色模式变化 onColorModeChange(): void { this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; AppStorage.setOrCreate('isDarkMode', this.isDarkMode); } // 组件生命周期 aboutToDisappear() { // 无需处理apiDialogController } applyThemeMode(mode: number) { let colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET if (mode === 1) { colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT } else if (mode === 2) { colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK } AppStorage.setOrCreate('currentColorMode', colorMode) AppStorage.setOrCreate('isDarkMode', colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) PreferencesUtil.putSync(SettingPage.THEME_MODE, mode) AppStorage.setOrCreate('themeMode', mode) // 只有强制浅色/深色时才主动设置 const context = getContext(this) as common.UIAbilityContext context.getApplicationContext().setColorMode(colorMode) } private logNetDisk(level: 'info' | 'warn' | 'error', message: string) { const tag = 'NetDiskSetting'; switch (level) { case 'info': void ServerLogUtil.info(tag, message); break; case 'warn': void ServerLogUtil.warn(tag, message); break; case 'error': void ServerLogUtil.error(tag, message); break; default: break; } } private handleClearWebDavCache() { if (this.isClearingCache) { return; } this.isClearingCache = true; const manager = RemoteDriveManager.getInstance(); const account = manager?.currentAccount; const accountId = account?.id; const clearPromise = accountId !== undefined ? clearWebDavCacheByAccount(accountId) : clearWebDavCaches(); const target = accountId !== undefined && account ? ServerLogUtil.sanitizeAccount(account) : 'all-accounts'; this.logNetDisk('info', `开始清除网盘缓存: target=${target}`); clearPromise.then(() => { ToastUtil.showToast('已清除网盘缓存'); this.logNetDisk('info', `清除网盘缓存成功: target=${target}`); }).catch((error: Error) => { hilog.error(0, 'SettingPage', `清除网盘缓存失败: ${error.message}`); ToastUtil.showToast('清除失败,请稍后重试'); this.logNetDisk('error', `清除网盘缓存失败: target=${target}, err=${error.message}`); }).finally(() => { this.isClearingCache = false; this.logNetDisk('info', `网盘缓存清理结束: target=${target}`); }); } private handleClearLogFiles() { if (this.isClearingLogs) { return; } // 显示确认对话框 AlertDialog.show({ title: '确认清除', message: '确定要清除所有日志文件吗?此操作不可撤销。', autoCancel: true, alignment: DialogAlignment.Bottom, primaryButton: { value: '确定清除', action: () => { this.clearLogFiles(); } }, secondaryButton: { value: '取消', action: () => { // 取消操作 } } }); } private deleteDirectoryRecursively(dirPath: string): void { try { if (!FileUtil.accessSync(dirPath)) { return; } if (FileUtil.isDirectory(dirPath)) { const files = FileUtil.listFileSync(dirPath); files.forEach((file: string) => { const filePath = `${dirPath}${FileUtil.separator}${file}`; this.deleteDirectoryRecursively(filePath); }); FileUtil.rmdirSync(dirPath); } else { FileUtil.unlinkSync(dirPath); } } catch (error) { hilog.warn(0, 'SettingPage', `删除目录失败: ${dirPath}, 错误: ${JSON.stringify(error)}`); } } private async clearLogFiles() { this.isClearingLogs = true; try { let clearedCount = 0; // 清除错误日志 const errorLogPath = FileUtil.getFilesDirPath('ErrorLog', 'errorLog.txt'); if (FileUtil.accessSync(errorLogPath)) { FileUtil.unlinkSync(errorLogPath); clearedCount++; } // 清除Navidrome日志 const navidromeLogDir = FileUtil.getFilesDirPath('NavidromeLog'); if (FileUtil.accessSync(navidromeLogDir)) { try { const files = FileUtil.listFileSync(navidromeLogDir); files.forEach((file: string) => { const filePath = `${navidromeLogDir}${FileUtil.separator}${file}`; if (FileUtil.accessSync(filePath) && !FileUtil.isDirectory(filePath)) { FileUtil.unlinkSync(filePath); clearedCount++; } }); } catch (error) { hilog.warn(0, 'SettingPage', `清除Navidrome日志目录时出错: ${JSON.stringify(error)}`); } } // 清除日志上传缓存 const logUploadDir = FileUtil.getCacheDirPath('LogUpload'); if (FileUtil.accessSync(logUploadDir)) { try { // 递归删除目录及其内容 this.deleteDirectoryRecursively(logUploadDir); clearedCount++; } catch (error) { hilog.warn(0, 'SettingPage', `清除日志上传缓存时出错: ${JSON.stringify(error)}`); } } // 清除其他可能的日志文件 const logFilePatterns = [ 'app.log', 'debug.log', 'info.log', 'warn.log', 'crash.log' ]; logFilePatterns.forEach((fileName: string) => { try { const filesDir = AppUtil.getContext().filesDir; const logFilePath = `${filesDir}${FileUtil.separator}${fileName}`; if (FileUtil.accessSync(logFilePath)) { FileUtil.unlinkSync(logFilePath); clearedCount++; } // 检查cache目录 const cacheLogPath = `${AppUtil.getContext().cacheDir}${FileUtil.separator}${fileName}`; if (FileUtil.accessSync(cacheLogPath)) { FileUtil.unlinkSync(cacheLogPath); clearedCount++; } } catch (error) { hilog.warn(0, 'SettingPage', `清除日志文件 ${fileName} 时出错: ${JSON.stringify(error)}`); } }); if (clearedCount > 0) { ToastUtil.showToast(`已清除 ${clearedCount} 个日志文件`); hilog.info(0, 'SettingPage', `成功清除 ${clearedCount} 个日志文件`); } else { ToastUtil.showToast('未找到需要清除的日志文件'); } } catch (error) { const errorMessage = error instanceof Error ? error.message : '未知错误'; hilog.error(0, 'SettingPage', `清除日志文件失败: ${errorMessage}`); ToastUtil.showToast('清除失败,请稍后重试'); } finally { this.isClearingLogs = false; } } @Builder pickerBuilder() { Column({ space: 20 }) { HSBColorPicker({ color: this.customColor, radius: 8, onChange: (value: string) => { this.customColor = value } }) .layoutWeight(1) .padding(15) Row({ space: 10 }) { Button('取消') .stateEffect(true) .backgroundColor(this.themeColor) .onClick(() => { this.showColorPicker = false }) Button('确定') .stateEffect(true) .backgroundColor(this.themeColor) .onClick(() => { this.themeColor = this.customColor PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, this.customColor) AppStorage.setOrCreate('themeColor', this.customColor) this.sendChangeEvent() this.showColorPicker = false }) } } .padding(20) .width('80%') .height(300) } @Builder themeSheetBuilder() { Column() { // 颜色模式分组卡片 Column() { Row() { Row() { Image($r('app.media.theme')) .width(20) .height(20) .fillColor(this.themeColor) Text('颜色模式') .fontSize(15) .margin({ left: 6 }) .fontWeight(500) } .layoutWeight(1) Blank() Row() { ForEach(['自动', '日间', '夜间'], (item: string, idx: number) => { Column() { Radio({ value: idx.toString(), group: this.colorGroup, }) .checked(this.themeMode === idx) .radioStyle({ checkedBackgroundColor: this.themeColor }) .margin({ left: 3, right: 3 }) .onClick(() => { this.themeMode = idx this.applyThemeMode(idx) this.sendChangeEvent() }) Text(item) .fontSize(15) .fontColor($r('app.color.text_color')) .margin({ top: 6 }) .onClick(() => { this.themeMode = idx this.applyThemeMode(idx) this.sendChangeEvent() }) } .alignItems(HorizontalAlign.Center) .margin({ left: 12, right: 12 }) }) } .margin({ left: 12, right: 12 }) } } .backgroundColor($r('app.color.settings_background_main')) .borderRadius(18) .border({ width: 1, color: '#F0F0F0' }) .shadow({ radius: 12, color: 0x11000000, offsetX: 0, offsetY: 2 }) .margin({ left: 0, right: 0, bottom: 20 }) .padding({ top: 18, bottom: 18, left: 20, right: 20 }) .width('90%') // 主题色分组卡片 Column() { Row() { SymbolGlyph($r('sys.symbol.paintpalette')) .fontSize(20) .fontColor([this.themeColor]) Text('主题色') .fontSize(15) .fontWeight(500) .margin({ left: 8 }) .layoutWeight(1) } .margin({ left: 20, top: 12 }) Row() { Column() { ForEach(this.colorRows, (row: Array, rowIdx: number) => { Row() { ForEach(row, (item: ThemeColorItem, colIdx: number) => { Button() { Row() { Blank() .width(22) .height(22) .backgroundColor(item.name === '自定义' && this.isCustomThemeColor() ? this.themeColor : item.color) .border({ width: 2, color: $r('app.color.text_color') }) .borderRadius(11) Text(item.name) .fontSize(15) .fontColor($r('app.color.text_color')) .margin({ left: 10 }) // Text(item.isVip?'VIP':"Free") // .fontSize(10) // .fontColor(item.isVip?'#FFD700':"#000000") // 金色 // .backgroundColor('#FFF9E3') // .borderRadius(6) // .padding({ left: 4, right: 4, top: 1, bottom: 1 }) // .margin({ left: 4 }) } .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Start) .layoutWeight(1) } .height(40) .layoutWeight(1) .backgroundColor( (item.name === '自定义' && this.isCustomThemeColor()) || this.themeColor === item.color ? this.themeColor : $r('app.color.settings_background_main') ) .borderRadius(20) .onClick(() => { if (item.isVip) { if (!Utility.isNoble()) { this.showVipDialog(); return; } } if (item.name === '自定义') { this.showColorPicker = true } else { this.themeColor = item.color PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, item.color) AppStorage.setOrCreate('themeColor', item.color) this.sendChangeEvent() } }) .margin({ right: colIdx === 0 ? '4%' : 20, bottom: 10, left: 20 }) }) } .justifyContent(FlexAlign.Start) }) } .margin({ left: 12, right: 12, top: 12 }) } } .width('90%') .backgroundColor($r('app.color.settings_background_main')) .borderRadius(18) .border({ width: 1, color: '#F0F0F0' }) .shadow({ radius: 12, color: 0x11000000, offsetX: 0, offsetY: 2 }) .margin({ left: 0, right: 0, bottom: 18 }) .padding({ top: 18, bottom: 18, left: 0, right: 0 }) .bindPopup(this.showColorPicker, { builder: this.pickerBuilder(), placement: Placement.Top, mask: { color: '#33000000' }, enableArrow: false, //是否显示箭头 showInSubWindow: false, onStateChange: (e) => { if (!e.isVisible) { this.showColorPicker = false } } }) // 主题色自定义弹窗 } .padding({ top: 8, bottom: 8, left: 15, right: 15 }) .width('100%') .backgroundColor(Color.Transparent) .borderRadius(24) } @Builder topTitleBar(){ Column() { Row({ space: 15 }) { //左侧滑动按钮 Button({ type: ButtonType.Circle, stateEffect: true }) { SymbolGlyph($r('sys.symbol.chevron_left')) .attributeModifier(new SymbolGlyphFancyModifier(25, '', '')) } .attributeModifier(new ButtonFancyModifier(40, 40)) .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 }) .animation({ duration: 300, curve: Curve.Ease }) .onClick(() => { this.getUIContext()?.animateTo({ duration: 555 }, () => { this.mType =0 }) }) .attributeModifier(new ShadowModifier()) .zIndex(0) Text($r('app.string.setting')) .margin({left:3,right:10}) .fontColor($r('app.color.text_color')) .fontSize(19) .maxLines(1) .textOverflow({ overflow: TextOverflow.MARQUEE })//超长滚动 .layoutWeight(1) .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 }) } } .padding({ top: this.topSafeHeight+10, left: 10, right: 10,bottom:12 }) .width('100%') } build() { Column() { this.topTitleBar() // Column() { // Line().width('100%').height('100%') // } // .height(this.topRectHeight) // .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor) // .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]) // // // 自定义标题栏 // Stack() { // // 居中标题 // Text('通用设置') // .fontSize(20) // .fontColor(Color.White) // .align(Alignment.Center) // // 左侧返回按钮 // Row() { // Image($r('app.media.left_back_white')) // .width(26) // .height(26) // .margin({ left: 12, right: 8 }) // .onClick(() => { // this.getUIContext()?.animateTo({ duration: 555 }, () => { // // 动画闭包内控制Image组件的出现和消失 // // this.isShowDrawer = !this.isShowDrawer // // this.offsetX = 0 // this.mType =0 // }) // }) // Blank().flexGrow(1) // Blank().width(32) // } // .height(48) // .width('100%') // .alignItems(VerticalAlign.Center) // } // .height(48) // .width('100%') // .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor) Scroll() { Column() { // 主题设置分组 Column() { Row() { Text('个性化') .margin({ left: 18, right: 20 }) .fontSize(16) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) } .height(48) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 主题设置弹框入口 Button({ type: ButtonType.Normal, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.sun_max')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('主题设置') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Image($r('app.media.arrow_right')) .width(22) .height(22) .margin({ right: 18 }) } } .backgroundColor(Color.Transparent) .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) .onClick(() => { this.showColorPicker = false; this.isThemeSheet = true; this.customColor = this.themeColor; }) .bindSheet($$this.isThemeSheet, this.themeSheetBuilder(), { height: '95%', dragBar: true, preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM, showClose: true, blurStyle: BlurStyle.Thin, backgroundColor: Color.Transparent, title: { title: '主题设置' }, shouldDismiss: (SheetDismiss: SheetDismiss) => { SheetDismiss.dismiss(); this.showColorPicker = false; } }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) Button({ type: ButtonType.Normal, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.paintpalette')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('自定义背景') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) .bindSheet($$this.isCustomizeBgSheet, this.customizeBgSheet(), { height: '95%', dragBar: true, preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM, showClose: true, blurStyle: BlurStyle.Thin, backgroundColor: Color.Transparent, title: { title: '自定义背景' } }) Blank() // 右侧箭头 Image($r('app.media.arrow_right')) .width(22) .height(22) .margin({ left: 20, right: 20 }) .align(Alignment.Center) } } .clickEffect({ level: ClickEffectLevel.HEAVY }) .height(55) .onClick(() => { if (!Utility.isNoble()) { this.showVipDialog(); return; } this.isCustomizeBgSheet = !this.isCustomizeBgSheet; }) .backgroundColor(Color.Transparent) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) Button({ type: ButtonType.Normal, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.satellite_map')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('自定义图标') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) .bindSheet($$this.isCustomizeICONSheet, this.customizeICONSheet(), { height: this.isLandscape ? '95%' : '85%', dragBar: true, preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM, showClose: true, blurStyle: BlurStyle.Thin, backgroundColor: Color.Transparent, title: { title: '自定义图标' } }) Blank() // 右侧箭头 Image($r('app.media.arrow_right')) .width(22) .height(22) .margin({ left: 20, right: 20 }) .align(Alignment.Center) } } .clickEffect({level:ClickEffectLevel.HEAVY}) .height(55) .onClick(() => { if (!Utility.isNoble()) { this.showVipDialog(); return; } this.isCustomizeICONSheet = !this.isCustomizeICONSheet; }) .backgroundColor(Color.Transparent) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 滚动隐藏' // Row() { // Text('滚动隐藏') // .margin({ left: 18 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Toggle({ type: ToggleType.Switch, isOn: this.isScrollHide }) // .selectedColor(this.themeColor) // .switchPointColor(Color.White) // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) // .margin({ right: 18 }) // .onChange((checked: boolean) => { // this.isScrollHide = checked; // PreferencesUtil.put(SettingPage.IS_SCROLL_HIDE, this.isScrollHide) // this.sendChangeEvent() // }) // .width(50) // .height(30); // } // .height(55) // .visibility(Visibility.None) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // .visibility(Visibility.None) // 网格布局 // 网格布局 Row() { SymbolGlyph($r('sys.symbol.more')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('布局模式') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([ { value: CommonConstants.DEFAULT_LAYOUT[0] }, { value: CommonConstants.DEFAULT_LAYOUT[1] }, { value: CommonConstants.DEFAULT_LAYOUT[2] }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({ right: 18 }) .selected(this.twoFingerType==4?0: this.isGridMusic?2:1) .value(CommonConstants.DEFAULT_LAYOUT[this.twoFingerType==4?0: this.isGridMusic?2:1]) .onSelect(async (_index: number, text?: string | undefined) => { if(_index == 0){ PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,4) }else{ if(this.twoFingerType!=4){ PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,this.twoFingerType) }else{ PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,3) } if(_index == 1){ PreferencesUtil.put(SettingPage.IS_GRID_MUSIC,false) }else{ PreferencesUtil.put(SettingPage.IS_GRID_MUSIC,true) } } this.sendChangeEvent() }) } .height(55) .clickEffect({level:ClickEffectLevel.HEAVY}) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 封面方形 Row() { SymbolGlyph($r('sys.symbol.rectangle')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('封面方形') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCoverRectangle }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isCoverRectangle = checked; PreferencesUtil.put(SettingPage.IS_COVER_RECTANGLE, this.isCoverRectangle) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) //导入视频复制一份到DownLoad目录 Row() { SymbolGlyph($r('sys.symbol.save')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('导入音乐复制到DownLoad目录') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCopyFileToDownLoad }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { // if(!this.isCopyFileToDownLoad){ // ToastUtil.showToast("读取内嵌封面和歌词功能需要开启导入复制开关,不然没有权限读取。") // } this.isCopyFileToDownLoad = checked; PreferencesUtil.put(SettingPage.IS_COPYFILE_TO_DOWNLOAD, this.isCopyFileToDownLoad) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({level:ClickEffectLevel.HEAVY}) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) //播放列表透明 Row() { SymbolGlyph($r('sys.symbol.circle_lefthalf_inset_filled')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('播放列表背景透明') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isPlayListBgGrass }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isPlayListBgGrass = checked; PreferencesUtil.put(SettingPage.IS_PLAYLIST_BG_GRASS, this.isPlayListBgGrass) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 网格封面大 Row() { SymbolGlyph($r('sys.symbol.picture')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('列表封面大小') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([ { value: CommonConstants.TWO_FINGER_TYPE[0] }, { value: CommonConstants.TWO_FINGER_TYPE[1] }, { value: CommonConstants.TWO_FINGER_TYPE[2] }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({ right: 18 }) .selected(this.twoFingerType - 1) .value(CommonConstants.TWO_FINGER_TYPE[this.twoFingerType-1]) .onSelect(async (_index: number, text?: string | undefined) => { _index++; this.twoFingerType = _index PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE, this.twoFingerType) this.sendChangeEvent() }) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 封面顶部 Row() { SymbolGlyph($r('sys.symbol.arrowshape_up')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('封面顶部') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCoverTop }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isCoverTop = checked; PreferencesUtil.put(SettingPage.IS_COVER_TOP, this.isCoverTop) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) .opacity(this.isCoverTop ? 1 : 0) .visibility(this.isCoverTop ? Visibility.Visible : Visibility.None) .animation({ duration: 500, curve: 'ease-in-out' // 可选动画曲线 }) // 封面顶部 Row() { SymbolGlyph($r('sys.symbol.shutter_photo')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('顶部大封面') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCoverTopBig }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isCoverTopBig = checked; if(this.isCoverTopBig){ ToastUtil.showToast('启动该开关部分设备封面太大导致和音乐控制重叠!') } PreferencesUtil.put(SettingPage.IS_COVER_TOP_BIG, this.isCoverTopBig) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) .opacity(this.isCoverTop ? 1 : 0) .visibility(this.isCoverTop ? Visibility.Visible : Visibility.None) .animation({ duration: 500, curve: 'ease-in-out' // 可选动画曲线 }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 切歌动画效果 Row() { SymbolGlyph($r('sys.symbol.music')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('切歌动画效果') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.openSkipSongAnimate }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.openSkipSongAnimate = checked; PreferencesUtil.put(SettingPage.OPEN_SKIPSONG_ANIMATE, this.openSkipSongAnimate) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 圆形播放按钮 Row() { SymbolGlyph($r('sys.symbol.circle')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('圆形播放按钮') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCircleBtn }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isCircleBtn = checked; PreferencesUtil.put(SettingPage.IS_CIRCLE_BTN, this.isCircleBtn) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) } .transition(TransitionEffect.move(TransitionEdge.BOTTOM) .animation({ duration: 500, curve: Curve.Ease, delay: 260 })) .backgroundColor($r('app.color.settings_background_main')) .borderRadius(20) .margin({ left: 0, right: 0, top: 0, bottom: 10 }) .padding(0) // 网络工具 // Column() { // Row() { // Text('网络工具') // .margin({ left: 18, right: 20 }) // .fontSize(16) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // } // .height(48) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // Button({ type: ButtonType.Normal, stateEffect: true }) { // Row() { // Image($r('app.media.cloudDisk')) // .width(22) // .height(22) // .alignSelf(ItemAlign.Center) // .margin({ left: 15 }) // Text('SMB 测试工具') // .margin({ left: 8 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Image($r('app.media.arrow_right')) // .width(22) // .height(22) // .margin({ right: 18 }) // } // } // .height(55) // .backgroundColor(Color.Transparent) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // .onClick(() => { // router.pushUrl({ // url: 'pages/SmbTestPage' // }); // }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // } // .transition(TransitionEffect.move(TransitionEdge.BOTTOM) // .animation({ duration: 500, curve: Curve.Ease, delay: 260 })) // .backgroundColor($r('app.color.settings_background_main')) // .borderRadius(20) // .margin({ // left: 0, // right: 0, // top: 0, // bottom: 10 // }) // .padding(0) // 音频设置分组 Column() { Row() { Text('音频设置') .margin({ left: 18, right: 20 }) .fontSize(16) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) } .height(48) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 启动时播放 Row() { SymbolGlyph($r('sys.symbol.play_circle')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('启动时播放') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isStartAutoPlay }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isStartAutoPlay = checked; PreferencesUtil.put(SettingPage.iS_START_AUTO_PLAY, this.isStartAutoPlay) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 列表是否可左滑 Row() { SymbolGlyph($r('sys.symbol.indentation_left')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('列表是否可左滑') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isSwipe }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isSwipe = checked; PreferencesUtil.put(SettingPage.IS_SWIPE, this.isSwipe) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({level:ClickEffectLevel.HEAVY}) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 记住播放进度 Row() { SymbolGlyph($r('sys.symbol.rectangle_split_3x1')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('记住最后一首进度') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isMemoryLastPlay }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isMemoryLastPlay = checked; PreferencesUtil.put(SettingPage.iS_MEMORY_LAST_PLAY, this.isMemoryLastPlay) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 记忆播放 Row() { SymbolGlyph($r('sys.symbol.route_plan')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('记忆播放') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isMusicMemoryPlay = checked; PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) //显示快进快退 Row() { SymbolGlyph($r('sys.symbol.hand_point_up_tap')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('显示快进快退') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowBackFast }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isShowBackFast = checked; PreferencesUtil.put('isShowBackFast', this.isShowBackFast) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) .opacity(this.isShowBackFast ? 1 : 0) .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None) .animation({ duration: 500, curve: 'ease-in-out' // 可选动画曲线 }) // 快进快退时长 Row() { SymbolGlyph($r('sys.symbol.hand_tap_wave_2')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('快进快退时长') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) SelectItem({ list: this.fastForwardSecond.map(opt => opt.label), selected: this.fastForwardSecond.findIndex(opt => opt.value === this.fastForwardSeconds), onChange: (index: number) => { this.fastForwardSeconds = this.fastForwardSecond[index].value; PreferencesUtil.put('fastForwardSeconds', this.fastForwardSeconds) this.sendChangeEvent() } }) } .height(55) .opacity(this.isShowBackFast ? 1 : 0) .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None) .animation({ duration: 500, curve: 'ease-in-out' // 可选动画曲线 }) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 长按默认倍数 Row() { SymbolGlyph($r('sys.symbol.timer')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('长按默认倍数') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([//倍速 { value: '0.25x' }, { value: '0.5x' }, { value: '0.75x' }, { value: '1x' }, { value: '1.25x' }, { value: '1.5x' }, { value: '1.75x' }, { value: '2x' }, { value: '2.5x' }, { value: '3x' }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({right:18}) .selected(CommonConstants.video_speed_list.indexOf(this.longPressSpeed)) .value(Utility.optimizedFormat(this.longPressSpeed)) .onSelect(async (_index: number, text?: string | undefined) => { let speed = parseFloat(text?.replace('x', '') || '1'); if (!CommonConstants.video_speed_list.includes(speed)) { speed = 1; } this.longPressSpeed = speed PreferencesUtil.put(SettingPage.LONG_PRESS_SPEED, this.longPressSpeed) this.sendChangeEvent() }) } .height(55) .clickEffect({level:ClickEffectLevel.HEAVY}) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 默认排序模式 Row() { SymbolGlyph($r('sys.symbol.text_and_arrow_down')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('默认排序模式') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([ { value: CommonConstants.SORT_ARRAY[0] }, { value: CommonConstants.SORT_ARRAY[1] }, { value: CommonConstants.SORT_ARRAY[2] }, { value: CommonConstants.SORT_ARRAY[3] }, { value: CommonConstants.SORT_ARRAY[4] }, { value: CommonConstants.SORT_ARRAY[5] }, { value: CommonConstants.SORT_ARRAY[6] }, { value: CommonConstants.SORT_ARRAY[7] }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({ right: 18 }) .selected(this.sortType) .value(CommonConstants.SORT_ARRAY[this.sortType]) .onSelect(async (_index: number, text?: string | undefined) => { this.sortType = _index PreferencesUtil.put(SettingPage.SORT_TYPE, this.sortType) this.sendChangeEvent() }) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 首页默认切换媒体库 Row() { SymbolGlyph($r('sys.symbol.identify_song')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('首页默认媒体库') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.idDefaultMediaKu }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.idDefaultMediaKu = checked; PreferencesUtil.put('idDefaultMediaKu', this.idDefaultMediaKu) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 列表显示音乐文件名 Row() { SymbolGlyph($r('sys.symbol.text_clipboard')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('列表显示音乐文件名') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowFileName }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isShowFileName = checked; PreferencesUtil.put('isShowFileName', this.isShowFileName) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 网盘播放不跳转到首页 Row() { SymbolGlyph($r('sys.symbol.close_sidebar')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('网盘播放不跳转到首页') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isNoJumpToHome }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isNoJumpToHome = checked; PreferencesUtil.put('isNoJumpToHome', this.isNoJumpToHome) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 日志上传开关 Row() { SymbolGlyph($r('sys.symbol.cloud')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Column({ space: 4 }) { Text('开启日志上传') .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) Text('开启后,在关于我们页连点Logo 8次将收集并上传日志') .fontSize(12) .fontColor(Color.Gray) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) .margin({ left: 8 }) Toggle({ type: ToggleType.Switch, isOn: this.isLogUploadEnabled }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isLogUploadEnabled = checked; PreferencesUtil.put(SettingPage.LOG_UPLOAD_ENABLED, this.isLogUploadEnabled) if (checked) { const ok = this.ensureMeituUploadHandler(false); if (ok) { ToastUtil.showToast('已开启日志上传,关于我们页连点Logo 8次将上报') } } else { this.registerLogUploadDisabled(); ToastUtil.showToast('已关闭日志上传') } }) .width(50) .height(30); } .height(70) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 清除日志文件按钮 - 只在开启日志上传时显示 if (this.isLogUploadEnabled) { Row() { SymbolGlyph($r('sys.symbol.trash_fill')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Column({ space: 4 }) { Text('清除日志文件') .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) Text('清除本地保存的所有日志文件') .fontSize(12) .fontColor(Color.Gray) }.layoutWeight(1).margin({ left: 8 }) .alignItems(HorizontalAlign.Start) Text(this.isClearingLogs ? '清除中…' : '立即清除') .margin({ right: 18 }) .fontSize(13) .fontColor(this.themeColor) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) .onClick(() => { this.handleClearLogFiles(); }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) } Row() { SymbolGlyph($r('sys.symbol.trash')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('清除网盘缓存') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Text(this.isClearingCache ? '清理中…' : '立即清理') .margin({ right: 18 }) .fontSize(13) .fontColor(this.themeColor) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) .onClick(() => { this.handleClearWebDavCache(); }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // WebDAV上传默认重复文件处理方式 Row() { SymbolGlyph($r('sys.symbol.doc')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('上传重复文件处理') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([ { value: '跳过' }, { value: '覆盖' }, { value: '重命名' }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({ right: 18 }) .selected(this.webdavUploadDuplicateAction === 'skip' ? 0 : this.webdavUploadDuplicateAction === 'overwrite' ? 1 : 2) .value(this.webdavUploadDuplicateAction === 'skip' ? '跳过' : this.webdavUploadDuplicateAction === 'overwrite' ? '覆盖' : '重命名') .onSelect((_index: number, text?: string | undefined) => { if (_index === 0) { this.webdavUploadDuplicateAction = 'skip'; } else if (_index === 1) { this.webdavUploadDuplicateAction = 'overwrite'; } else { this.webdavUploadDuplicateAction = 'rename'; } PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_DUPLICATE_ACTION, this.webdavUploadDuplicateAction) }) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // WebDAV上传完成后自动清理队列 Row() { SymbolGlyph($r('sys.symbol.trash')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('上传完成自动清理队列') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.webdavUploadAutoClear }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.webdavUploadAutoClear = checked; PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_AUTO_CLEAR, this.webdavUploadAutoClear) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // WebDAV是否允许移动网络上传 Row() { SymbolGlyph($r('sys.symbol.wifi')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('允许移动网络上传') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.webdavUploadAllowMobile }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.webdavUploadAllowMobile = checked; PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_ALLOW_MOBILE, this.webdavUploadAllowMobile) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // WebDAV上传失败自动重试次数 Row() { SymbolGlyph($r('sys.symbol.arrow_clockwise')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('上传失败重试次数') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Select([ { value: '0次' }, { value: '1次' }, { value: '2次' }, { value: '3次' }, { value: '5次' }]) .font({ size: 15, weight: FontWeight.Medium }) .fontColor(Color.Gray) .margin({ right: 18 }) .selected(this.webdavUploadRetryCount === 0 ? 0 : this.webdavUploadRetryCount === 1 ? 1 : this.webdavUploadRetryCount === 2 ? 2 : this.webdavUploadRetryCount === 3 ? 3 : 4) .value(this.webdavUploadRetryCount === 0 ? '0次' : this.webdavUploadRetryCount === 1 ? '1次' : this.webdavUploadRetryCount === 2 ? '2次' : this.webdavUploadRetryCount === 3 ? '3次' : '5次') .onSelect((_index: number, text?: string | undefined) => { if (_index === 0) { this.webdavUploadRetryCount = 0; } else if (_index === 1) { this.webdavUploadRetryCount = 1; } else if (_index === 2) { this.webdavUploadRetryCount = 2; } else if (_index === 3) { this.webdavUploadRetryCount = 3; } else { this.webdavUploadRetryCount = 5; } PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_RETRY_COUNT, this.webdavUploadRetryCount) }) } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 长歌名滚动 Row() { SymbolGlyph($r('sys.symbol.close_sidebar')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('长歌名滚动') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isLongNameRoLL }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isLongNameRoLL = checked; PreferencesUtil.put('isLongNameRoLL', this.isLongNameRoLL) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 音量优化 Row() { SymbolGlyph($r('sys.symbol.speaker')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('音量优化') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.volumeSmall }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.volumeSmall = checked; if(this.volumeSmall){ ToastUtil.showToast('打开音量优化会比平时音量声音低些') } PreferencesUtil.put('volumeSmall', this.volumeSmall) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 智能解析 Row() { SymbolGlyph($r('sys.symbol.t_circle')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('智能文件名解析歌曲标签') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.autoParseMusicName }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.autoParseMusicName = checked; PreferencesUtil.put('autoParseMusicName', this.autoParseMusicName) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 保存播放模式 Row() { SymbolGlyph($r('sys.symbol.clock')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('保存播放模式') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isSavePlayMode = checked; PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) Row() { SymbolGlyph($r('sys.symbol.sun_max')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('与其他应用同时播放') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isSameTimePlay }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isSameTimePlay = checked; PreferencesUtil.put(SettingPage.IS_SAMETIME_PLAY, this.isSameTimePlay) this.sendChangeEvent() }) .width(50) .height(30); } .height(55).clickEffect({ level: ClickEffectLevel.HEAVY }) // .visibility(Visibility.None) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 播放背景随音乐封面 Row() { SymbolGlyph($r('sys.symbol.paperplane')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('播放背景随音乐封面') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isMusicBGCover = checked; PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover) }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) } .transition(TransitionEffect.move(TransitionEdge.BOTTOM) .animation({ duration: 500, curve: Curve.Ease, delay: 400 })) .backgroundColor($r('app.color.settings_background_main')) .borderRadius(20) .margin({ left: 0, right: 0, top: 10, bottom: 10 }) .padding(0) // API设置分组 this.apiBuilder() //设置教程 this.jcBuilder() //显示与隐藏设置 this.xsBuilder() //空白 Column() { Blank() .height(88) }.height(88) } .margin({ left: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20, right: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20, top: 20, bottom: 20 }) .justifyContent(FlexAlign.Start) } .scrollBar(BarState.Auto) .width('100%') .margin({ bottom: 10 }) .backgroundColor($r('app.color.settings_background')) } .layoutWeight(1) .height('100%') .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) } @Builder xsBuilder() { // 显示和隐藏分组 Column() { Row() { Text('显示隐藏') .margin({ left: 18, right: 20 }) .fontSize(16) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) } .onClick(() => { ToastUtil.showToast(this.appIdentifier) PreferencesUtil.putSync('isShowWX',true) }) .height(48) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) Row() { SymbolGlyph($r('sys.symbol.text_clipboard')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('滚动隐藏标题栏') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.autoHideTitle }) .selectedColor(this.themeColor) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .switchPointColor(Color.White) .margin({ right: 18 }) .onChange((checked: boolean) => { this.autoHideTitle = checked; PreferencesUtil.put('autoHideTitle', this.autoHideTitle) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // Row() { // SymbolGlyph($r('sys.symbol.label')) // .fontSize(20) // .fontColor([this.themeColor]) // .alignSelf(ItemAlign.Center) // .margin({ left: 15 }) // Text('显示播放全部') // .margin({ left: 8 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Toggle({ type: ToggleType.Switch, isOn: this.isShowAllBar }) // .selectedColor(this.themeColor) // .switchPointColor(Color.White) // .margin({ right: 18 }) // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) // .onChange((checked: boolean) => { // this.isShowAllBar = checked; // PreferencesUtil.put(SettingPage.IS_SHOW_ALLBAR, this.isShowAllBar) // this.sendChangeEvent() // }) // .width(50) // .height(30); // } // .height(55) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 显示私密音频 // Row() { // SymbolGlyph($r('sys.symbol.lock')) // .fontSize(20) // .fontColor([this.themeColor]) // .alignSelf(ItemAlign.Center) // .margin({ left: 15 }) // Text('显示私密音频') // .margin({ left: 8 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Toggle({ type: ToggleType.Switch, isOn: this.isShowSimi }) // .selectedColor(this.themeColor) // .switchPointColor(Color.White) // .margin({ right: 18 }) // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) // .onChange((checked: boolean) => { // this.isShowSimi = checked; // PreferencesUtil.put(SettingPage.IS_SHOW_SIMI, this.isShowSimi) // this.sendChangeEvent() // }) // .width(50) // .height(30); // } // .height(55) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 播放页单行歌词 Row() { SymbolGlyph($r('sys.symbol.close_sidebar')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('播放页单行歌词') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowSingleLineLyric }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isShowSingleLineLyric = checked; PreferencesUtil.put(SettingPage.IS_SHOW_SLLYRIC, this.isShowSingleLineLyric) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 二级菜单新风格 // Row() { // SymbolGlyph($r('sys.symbol.satellite_map')) // .fontSize(20) // .fontColor([this.themeColor]) // .alignSelf(ItemAlign.Center) // .margin({ left: 15 }) // Text('二级菜单新风格') // .margin({ left: 8 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Toggle({ type: ToggleType.Switch, isOn: this.isShowHeader }) // .selectedColor(this.themeColor) // .switchPointColor(Color.White) // .margin({ right: 18 }) // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) // .onChange((checked: boolean) => { // this.isShowHeader = checked; // PreferencesUtil.put(SettingPage.IS_SHOW_HEADER, this.isShowHeader) // this.sendChangeEvent() // }) // .width(50) // .height(30); // } // .height(55) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) //播控条显示上一首按钮 Row() { SymbolGlyph($r('sys.symbol.arrow_left')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('播控条上一首按钮') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowPrecious }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isShowPrecious = checked; PreferencesUtil.put('isShowPrecious', this.isShowPrecious) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 播放页返回键 Row() { SymbolGlyph($r('sys.symbol.arrow_left')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('显示播放页返回键') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowPlayPageBack }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isShowPlayPageBack = checked; PreferencesUtil.put(SettingPage.IS_SHOW_PLAYPAGE_BACK, this.isShowPlayPageBack) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // // 自动隐藏进度条两侧的按钮 // Row() { // SymbolGlyph($r('sys.symbol.sun_max')) // .fontSize(20) // .fontColor([this.themeColor]) // .alignSelf(ItemAlign.Center) // .margin({ left: 15 }) // Text('自动隐藏进度条两侧的按钮') // .margin({ left: 8 }) // .fontSize(15) // .fontColor(Color.Gray) // .fontWeight(480) // .layoutWeight(1) // Toggle({ type: ToggleType.Switch, isOn: this.is_auto_hide_progress }) // .selectedColor(this.themeColor) // .switchPointColor(Color.White) // .margin({ right: 18 }) // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) // .onChange((checked: boolean) => { // this.is_auto_hide_progress = checked; // PreferencesUtil.put(SettingPage.IS_AUTO_HIDE_PROGRESS, this.is_auto_hide_progress) // this.sendChangeEvent() // }) // .width(50) // .height(30); // } // .height(55) // .clickEffect({ level: ClickEffectLevel.HEAVY }) // // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 显示我的收藏 Row() { SymbolGlyph($r('sys.symbol.heart')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('显示我的收藏') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowFAV }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isShowFAV = checked; PreferencesUtil.put(SettingPage.IS_SHOW_FAV, this.isShowFAV) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 显示最近播放 Row() { SymbolGlyph($r('sys.symbol.clock')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('显示最近播放') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isShowHistory }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .margin({ right: 18 }) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .onChange((checked: boolean) => { this.isShowHistory = checked; PreferencesUtil.put(SettingPage.IS_SHOW_HISTORY, this.isShowHistory) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) .clickEffect({ level: ClickEffectLevel.HEAVY }) } .transition(TransitionEffect.move(TransitionEdge.BOTTOM) .animation({ duration: 500, curve: Curve.Ease, delay: 600 })) .backgroundColor($r('app.color.settings_background_main')) .borderRadius(20) .margin({ left: 0, right: 0, top: 10, bottom: 20 }) .padding(0) } @Builder jcBuilder() { //设置教程 Button({ type: ButtonType.Capsule, stateEffect: true }) { Column() { Row() { SymbolGlyph($r('sys.symbol.hand_draw')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('设置教程:') .margin({ left: 8 }) .fontSize(15) .fontColor(Color.Gray) .fontWeight(480) Text('点击进Q群讨论') .margin({ right: 10 }) .fontSize(15) .fontColor(Color.Gray) .layoutWeight(1) Blank() // 右侧箭头 Image($r('app.media.arrow_right')) .width(22) .height(22) .margin({ left: 20, right: 20 }) .align(Alignment.Center) } .height(55) } } .clickEffect({ level: ClickEffectLevel.HEAVY }) .onClick(() => { const qqUrl = `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${CommonConstants.QQ_GROUP}&card_type=group&source=external` let context = this.getUIContext().getHostContext() as common.UIAbilityContext context.openLink(qqUrl, {}) }) .backgroundColor($r('app.color.settings_background_main')) .borderRadius(15) .margin({ top: 0, bottom: 20 }) .padding(0) .transition(TransitionEffect.move(TransitionEdge.BOTTOM) .animation({ duration: 500, curve: Curve.Ease, delay: 220 })) } @Builder apiBuilder() { // API设置分组 Column() { Row() { Text(){ Span('API设置') Span('\n(请注意:使用此功能您需拥有相关著作人的授权,否则可能导致版权法律纠纷,本软件不提供任何API,本软件对此不负任何责任。)') .fontColor(this.themeColor).fontSize(14) // .fontStyle(FontStyle.Italic) } .margin({ left: 18, right: 20 }) .fontSize(16) .fontColor(Color.Gray) .fontWeight(480) .layoutWeight(1) } .height(82) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 歌词API Button({ type: ButtonType.Normal, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.lightbulb')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('歌词:') .margin({ left: 8, right: 6 }) .fontSize(15) .fontColor(Color.Gray) Text(this.lyricApiUrl) .margin({ right: 10 }) .fontSize(15) .fontColor(Color.Gray) .layoutWeight(1) Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename')) .width(20) .height(20) .margin({ right: 18 }) } } .clickEffect({ level: ClickEffectLevel.HEAVY }) .backgroundColor(Color.Transparent) .onClick(() => { this.apiDialogType = 'lyric' this.tempApiUrl = this.lyricApiUrl this.apiDialogController.open() }) .height(55) Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color')) // 封面API Button({ type: ButtonType.Normal, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.picture')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text('封面:') .margin({ left: 8, right: 6 }) .fontSize(15) .fontColor(Color.Gray) Text(this.coverApiUrl) .margin({ right: 10 }) .fontSize(15) .fontColor(Color.Gray) .layoutWeight(1) Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename')) .width(20) .height(20) .margin({ right: 18 }) } } .clickEffect({ level: ClickEffectLevel.HEAVY }) .backgroundColor(Color.Transparent) .onClick(() => { this.apiDialogType = 'cover' this.tempApiUrl = this.coverApiUrl this.apiDialogController.open() }) .height(55) } .transition(TransitionEffect.move(TransitionEdge.BOTTOM) .animation({ duration: 500, curve: Curve.Ease, delay: 200 })) .backgroundColor($r('app.color.settings_background_main')) .borderRadius(20) .margin({ left: 0, right: 0, top: 10, bottom: 20 }) .padding(0) } @Builder customizeICONSheet() { Scroll() { Column() { CustomizeICON({ iconIndex:this.iconCurrentID, iconArray:this.iconArray, onIconChange:(iconId:string,iconUrl:string)=>{ this.iconCurrentID = iconId PreferencesUtil.put('iconCurrentID', this.iconCurrentID) PreferencesUtil.put('iconCurrentUrl', iconUrl) this.sendChangeEvent() } }) } } .width('100%') .height('100%') } //发送广播通知更新UI sendChangeEvent() { const eventData: emitter.EventData = {}; emitter.emit({ eventId: EventConstants.EVENT_SETTING_UPDATE }, eventData); // 发送广播通知更新doSwipBack } goSelectImage() { let selectUris: Array = []; let photoPicker = new photoAccessHelper.PhotoViewPicker(); let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目 photoPicker.select(photoSelectOptions).then(async (photoSelectResult: photoAccessHelper.PhotoSelectResult) => { //用一个全局变量存储返回的uri selectUris = photoSelectResult.photoUris; console.info('photoViewPicker.select to file succeed and uris are:' + selectUris); //使用fs.openSync接口,通过uri打开这个文件得到fd let file = fileIo.openSync(selectUris[0], fileIo.OpenMode.READ_ONLY); console.info('file fd: ' + file.fd); const timestamp: number = Math.floor(Date.now() / 1000); let name = timestamp + "_homebg" let imagePath = this.context.filesDir + FileUtil.separator + name imagePath = fileUri.getUriFromPath(imagePath) let file2 = fileIo.openSync(imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE) fileIo.copyFileSync(file.fd, file2.fd) fileIo.closeSync(file); fileIo.closeSync(file2); this.customizeBgPath = imagePath PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG_PATH, this.customizeBgPath) this.sendChangeEvent() }).catch((err: BusinessError) => { console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`); }) } @Builder customizeBgSheet() { Scroll() { Column() { this.CustomizeBg() } } .width('100%') .height('100%') } @Builder CustomizeBg() { Column() { Image(this.customizeBgPath) .height('42%') .alt($r('app.media.add_image2')) .objectFit(ImageFit.Contain) .borderRadius(15) .clip(true) .clickEffect({ level: ClickEffectLevel.HEAVY }) .blur(this.blurValue) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.6}) .brightness(this.bgBrightness + 0.8) .margin({ left: 30, right: 30, bottom: 20 }) .onClick(async () => { this.goSelectImage() }) Row() { Row() { Button('选择图片') .fontColor(Color.White) .fontSize(12) .height(48) .width(100) .clickEffect({ level: ClickEffectLevel.HEAVY }) .backgroundColor(this.themeColor) .stateEffect(true) .onClick(async () => { this.goSelectImage() }) } .height('100%') .justifyContent(FlexAlign.Center) .layoutWeight(1) } .width('100%') .height(58) .margin({ bottom: 20 }) Column() { Row() { Text('自定义背景:') .margin({ left: 18 }) .fontSize(15) .fontColor($r('app.color.text_color')) .fontWeight(480) .layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.isCustomizeBg }) .selectedColor(this.themeColor) .switchPointColor(Color.White) .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5}) .margin({ right: 18 }) .onChange((checked: boolean) => { this.isCustomizeBg = checked; PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG, this.isCustomizeBg) this.sendChangeEvent() }) .width(50) .height(30); } .height(55) } .backgroundColor($r('app.color.settings_background_main')) .borderRadius(15) .margin({ left: 30, right: 30, top: 0, bottom: 20 }) .padding(0) Column() { Row() { Text('背景模糊:') .margin({ left: 18 }) .fontSize(15) .fontColor($r('app.color.text_color')) .fontWeight(480) Slider({ value: this.blurValue, min: 0, max: 100, step: 1, style: SliderStyle.OutSet }) .blockColor(this.themeColor) .trackColor($r('app.color.speed_text_color')) .selectedColor($r('app.color.index_background')) .trackThickness(8) .onChange((value: number) => { this.blurValue = value; PreferencesUtil.put(SettingPage.CUSTOMIZE_BG_BLUR, this.blurValue) this.sendChangeEvent() }) .layoutWeight(1) } .height(55) } .backgroundColor($r('app.color.settings_background_main')) .borderRadius(15) .margin({ left: 30, right: 30, top: 0, bottom: 20 }) .padding(0) Column() { Row() { Text('背景亮度:') .margin({ left: 18 }) .fontSize(15) .fontColor($r('app.color.text_color')) .fontWeight(480) Slider({ value: this.bgBrightness, min: -0.4, max: 0.4, step: 0.1, style: SliderStyle.OutSet }) .blockColor(this.themeColor) .trackColor($r('app.color.speed_text_color')) .selectedColor($r('app.color.index_background')) .trackThickness(8) .onChange((value: number) => { this.bgBrightness = value; PreferencesUtil.put(SettingPage.BG_BRIGHTNESS, this.bgBrightness) this.sendChangeEvent() }) .layoutWeight(1) } .height(55) } .backgroundColor($r('app.color.settings_background_main')) .borderRadius(15) .margin({ left: 30, right: 30, top: 0, bottom: 20 }) .padding(0) } .margin({ bottom: 30 }) } // 判断当前主题色是否为自定义色 isCustomThemeColor(): boolean { for (let i = 0; i < SettingPage.THEME_COLOR_LIST.length - 1; i++) { if (SettingPage.THEME_COLOR_LIST[i].color === this.themeColor) { return false; } } return true; } // 会员功能弹窗 showVipDialog() { DialogHelper.showCustomContentDialog({ dialogId: 'vip', title: "友情提示", autoCancel: false, backCancel: true, contentBuilder: () => { this.customVipBuilder("该功能需开通会员,非常感谢您的支持!") }, buttons: [], }) } @Builder customVipBuilder(content: string) { Column() { Text(content) .fontColor(Color.Gray) .fontSize(16) .alignSelf(ItemAlign.Start) .margin({ bottom: 15 }) Row() { Button('取消') .fontColor(Color.White) .backgroundColor(this.themeColor) .height(50) .layoutWeight(1) .stateEffect(true) .margin({ right: 6 }) .onClick(() => { DialogHelper.closeDialog('vip'); }) Button('开通') .fontColor(Color.White) .layoutWeight(1) .height(50) .backgroundColor(this.themeColor) .stateEffect(true) .margin({ left: 6 }) .onClick(() => { this.isThemeSheet = false; DialogHelper.closeDialog('vip'); this.mType = 1//跳转到用户中心 // router.pushUrl({ // url: 'pages/UserCenter' // }, router.RouterMode.Single); }) } } .width("100%") .padding(10) } @State appIdentifier:string='' geIDD() { // 获取应用签名等信息示例代码 let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO; try { bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => { hilog.info(0x0000, 'testTag11', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data)); let inde = JSON.stringify(data) this.appIdentifier = inde.substring(inde.indexOf('appIdentifier'),inde.indexOf('"certificate')) hilog.info(0x0000, 'testTag11', 'appIdentifier Data: %{public}s', this.appIdentifier); }).catch((err: BusinessError) => { hilog.error(0x0000, 'testTag11', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message); }); } catch (err) { let message = (err as BusinessError).message; hilog.error(0x0000, 'testTag33', 'getBundleInfoForSelf failed: %{public}s', message); } } private getMeituConfig(): UploadConfig | null { // 尝试清理可能存在的旧token缓存,避免使用过期token try { PreferencesUtil.put(SettingPage.MEITU_UPLOAD_TOKEN_KEY, '') LogUtil.info('SettingPage', '已清理旧的UpToken缓存') } catch (error) { LogUtil.debug('SettingPage', '清理token缓存失败,继续生成新token') } // 每次都生成新的UpToken,避免使用过期token LogUtil.info('SettingPage', `生成新的UpToken,Bucket: ${SettingPage.MEITU_BUCKET}`) const token = UpTokenUtil.generateUpToken(SettingPage.MEITU_AK, SettingPage.MEITU_SK, SettingPage.MEITU_BUCKET, 3600) LogUtil.info('SettingPage', `UpToken生成完成,Token前缀: ${token.substring(0, 20)}...`) // Domain可以缓存,因为通常不会变化 let domain = PreferencesUtil.getStringSync(SettingPage.MEITU_UPLOAD_DOMAIN_KEY, SettingPage.MEITU_DOMAIN) if (!domain || domain.trim().length === 0) { domain = SettingPage.MEITU_DOMAIN PreferencesUtil.put(SettingPage.MEITU_UPLOAD_DOMAIN_KEY, domain) } if (!domain || domain.trim().length === 0) { LogUtil.warn('SettingPage', '日志上传未配置域名') return null } LogUtil.info('SettingPage', `上传配置 - Domain: ${domain}, Bucket: ${SettingPage.MEITU_BUCKET}`) return { uploadToken: token, domain: domain, keyPrefix: 'logs' } } private ensureMeituUploadHandler(isInit: boolean): boolean { const config = this.getMeituConfig() if (!config) { if (!isInit) { ToastUtil.showToast('未配置日志上传token/域名,已关闭开关') this.isLogUploadEnabled = false PreferencesUtil.put(SettingPage.LOG_UPLOAD_ENABLED, false) } this.registerLogUploadDisabled() return false } LogCollector.registerUploadHandler(async (filePath: string): Promise => { return await Uploader.uploadFile(filePath, config) }) return true } private registerLogUploadDisabled() { LogCollector.registerUploadHandler(async (filePath: string): Promise => { LogUtil.info('LogUpload', `日志上传开关关闭,跳过: ${filePath}`) return }) } } // 主题色类型声明 export interface ThemeColorItem { name: string; color: string; isVip: boolean; } // 工具函数:将一维数组分成每行2个的二维数组 function chunkArray(arr: Array, size: number): Array> { const result: Array> = []; for (let i = 0; i < arr.length; i += size) { const row: Array = []; for (let j = 0; j < size; j++) { if (i + j < arr.length) { row.push(arr[i + j]); } } result.push(row); } return result; }