SettingPage.ets 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923
  1. import TitleBar from '../view/TitleBar'
  2. import { promptAction, router } from '@kit.ArkUI'
  3. import { CommonConstants } from '../common/constants/CommonConstants'
  4. import { AppUtil, DeviceUtil, DisplayUtil, FileUtil, MD5, PreferencesUtil, ToastUtil } from '@pura/harmony-utils'
  5. import { CustomContentDialog } from '@kit.ArkUI'
  6. import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
  7. import common from '@ohos.app.ability.common';
  8. import { photoAccessHelper } from '@kit.MediaLibraryKit'
  9. import { fileIo, fileUri } from '@kit.CoreFileKit'
  10. import { BusinessError, emitter } from '@kit.BasicServicesKit'
  11. import { BreakpointTypeEnum } from '../common/util/BreakpointSystem'
  12. import { Utility } from '../common/util/Utility'
  13. import { HSBColorPicker } from '@keke/color-picker'
  14. import { DialogHelper } from '@pura/harmony-dialog'
  15. import { bundleManager } from '@kit.AbilityKit'
  16. import { hilog } from '@kit.PerformanceAnalysisKit'
  17. @Preview
  18. // @Entry
  19. @Component
  20. export struct SettingPage {
  21. @Consume isShowDrawer: boolean;
  22. @Consume offsetX: number;
  23. @Consume mType: number;
  24. static readonly THEME_MODE: string = 'themeMode';
  25. static readonly SORT_TYPE: string = 'musicSortType';
  26. static readonly IS_BGPLAY_OPEN: string = 'isBgPlayOpen';
  27. static readonly IS_AUTO_RATATE: string = 'isAutoRatate';
  28. static readonly iS_MEMORY_PLAY: string = 'isMemoryPlay';
  29. static readonly IS_MIDIACODEC_OPEN: string = 'isMediacodec';
  30. static readonly iS_MUSIC_MEMORY_PLAY: string = 'isMusicMemoryPlay';
  31. static readonly iS_MUSIC_BG_COVER: string = 'isMusicBGCover';
  32. static readonly iS_SAVE_PLAY_MODE: string = 'isSavePlayMode';
  33. static readonly IS_COVER_RECTANGLE: string = 'isCoverRectangle'; //封面圆形或者方形
  34. static readonly IS_SHOW_SIMI: string = 'isShowSimi';
  35. static readonly IS_SHOW_FAV: string = 'isShowFAV';
  36. static readonly IS_SHOW_HISTORY: string = 'isShowHistory';
  37. static readonly IS_CUSTOMIZE_BG: string = 'is_customize_bg';
  38. static readonly IS_GRID_MUSIC: string = 'is_grid_music';
  39. static readonly IS_CUSTOMIZE_BG_PATH: string = 'is_customize_bg_path';
  40. static readonly IS_SCROLL_HIDE: string = 'isAutoScrollHide';
  41. static readonly IS_SAMETIME_PLAY: string = 'isSameTimePlay';
  42. static readonly CUSTOMIZE_BG_BLUR: string = 'customize_bg_blur';
  43. static readonly BG_BRIGHTNESS: string = 'bg_brightness';
  44. static readonly IS_SHOW_ALLBAR: string = 'IS_SHOW_ALLBAR';
  45. static readonly IS_SHOW_TITLTBAR: string = 'IS_SHOW_TITLTBAR';
  46. static readonly IS_SHOW_PLAYPAGE_BACK: string = 'IS_SHOW_PLAYPAGE_BACK';
  47. static readonly IS_SHOW_SLLYRIC: string = 'IS_SHOW_SLLYRIC';
  48. static readonly IS_CIRCLE_BTN: string = 'isCircleBtn';
  49. static readonly IS_COVER_TOP: string = 'IS_COVER_TOP';
  50. static readonly IS_SHOW_HEADER: string = 'IS_SHOW_HEADER';
  51. static readonly IS_COVER_TOP_BIG: string = 'IS_COVER_TOP_BIG';
  52. public static THEME_COLOR_KEY: string = 'THEME_COLOR';
  53. public static TWO_FINGER_TYPE: string = 'twoFingerType';
  54. public static LONG_PRESS_SPEED: string = 'longPressSpeed';
  55. public static IS_PLAYLIST_BG_GRASS: string = 'isPlayListBgGrass';
  56. static readonly IS_SWIPE: string = 'isSwipe'
  57. static readonly IS_AUTO_HIDE_PROGRESS: string = 'IS_AUTO_HIDE_PROGRESS';
  58. public static OPEN_SKIPSONG_ANIMATE: string = 'openSkipSongAnimate';
  59. public static THEME_COLOR_LIST: Array<ThemeColorItem> = [
  60. { name: '玫瑰粉', color: '#FF4081', isVip: false },
  61. { name: '经典蓝', color: '#0A59F7', isVip: false },
  62. { name: '活力黄', color: '#FFC107', isVip: true },
  63. { name: '枫叶红', color: '#F44336', isVip: true },
  64. { name: '幻影紫', color: '#9C27B0', isVip: true },
  65. { name: '翡翠绿', color: '#64BB5C', isVip: true },
  66. { name: '竹青蓝', color: '#00BCD4', isVip: true },
  67. { name: '深空灰', color: '#607D8B', isVip: true },
  68. { name: '橙霞橙', color: '#FF9800', isVip: true },
  69. { name: '湖水蓝', color: '#00BFFF', isVip: true },
  70. { name: '柠檬绿', color: '#C6FF00', isVip: true },
  71. { name: '樱花粉', color: '#FF69B4', isVip: true },
  72. { name: '暮夜蓝', color: '#283593', isVip: true },
  73. { name: '薄荷青', color: '#1DE9B6', isVip: true },
  74. { name: '银沙灰', color: '#B0BEC5', isVip: true },
  75. { name: '自定义', color: '#ffecec', isVip: true }
  76. ];
  77. static readonly iS_START_AUTO_PLAY: string = 'isStartAutoPlay';
  78. static readonly iS_MEMORY_LAST_PLAY: string = 'isMemoryLastPlay';
  79. @State showApiDialog: boolean = false
  80. @State tempApiUrl: string = ''
  81. @State lyricApiUrl: string = PreferencesUtil.getStringSync('LRC_API', '')
  82. @State isBgPlayOpen: boolean = true //是否启用后台播放
  83. @State isAutoRatate: boolean = true //是否启用自动横竖屏
  84. @State isMemoryPlay: boolean = true //是否启用记忆播放
  85. @State isMediacodec: boolean = false //是否启用硬件解码
  86. @State isMusicMemoryPlay: boolean = false //是否启用记忆播放
  87. @State isMusicBGCover: boolean = true //播放背景随封面
  88. @State sortType: number = 4 //默认排序方式
  89. @State isStartAutoPlay: boolean = false //启动后自动播放
  90. @State isMemoryLastPlay: boolean = false //是否启用应用退出记忆最后一首的播放进度
  91. @State isShowSimi: boolean = false //是否显示私密音频
  92. @State isShowFAV: boolean = true //是否显示我的收藏
  93. @State isShowHistory: boolean = true //是否显示最近播放
  94. @State isShowPlayPageBack: boolean = false //是否显示播放页返回键
  95. @State isShowSingleLineLyric: boolean = false //是否显示播放页返回键
  96. @State isShowHeader: boolean = true
  97. @State isCustomizeBg: boolean = false //自定义背景界面
  98. @State isCustomizeBgSheet: boolean = false //自定义背景界面
  99. @State isShowTitleBar: boolean = true //是否显示分类导航条
  100. @State isShowAllBar: boolean = true //是否显示播放全部条
  101. @State longPressSpeed: number = 3 //长按默认倍数
  102. @State blurValue: number = 0 //背景模糊
  103. @State bgBrightness: number = 0 //背景亮度
  104. @State isGridMusic: boolean = true //是否网格布局
  105. @State isCircleBtn: boolean = false //是否圆形播放按钮
  106. @State twoFingerType: number = 3 //双指放大瘦小Grid或list的大小
  107. @State isScrollHide: boolean = false //是否滚动隐藏
  108. @State isSameTimePlay: boolean = false //是否和其他app同时播放
  109. @State isCoverRectangle: boolean = false
  110. @State isSavePlayMode: boolean = true
  111. @State isCoverTop: boolean = true
  112. @State isCoverTopBig: boolean = false//顶部大封面部分手机显示会和播放控制页重叠
  113. @State isSwipe: boolean = false //listItem的左滑开关
  114. @State isPlayListBgGrass: boolean = true//是否播放列表玻璃透明效果
  115. @State is_auto_hide_progress: boolean = false
  116. @State openSkipSongAnimate: boolean = true//切歌动画效果
  117. @State customizeBgPath: string | undefined = '';
  118. context = getContext(this);
  119. @State showCoverApiDialog: boolean = false
  120. @State tempCoverApiUrl: string = ''
  121. @State coverApiUrl: string = PreferencesUtil.getStringSync('COVER_API', '')
  122. @State apiDialogType: 'lyric' | 'cover' = 'lyric'
  123. @State themeMode: number = 0 // 0: 跟随系统, 1: 浅色, 2: 深色
  124. @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number =
  125. ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
  126. @StorageLink('isDarkMode') isDarkMode: boolean = false // 是否启用深色模式
  127. /** 当前断点类型(如大屏/小屏) */
  128. @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
  129. @State verName: string = ''
  130. @StorageProp('themeColor') themeColor: string =
  131. PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  132. @State showColorPicker: boolean = false
  133. @State customColor: string = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  134. @State isThemeSheet: boolean = false // 主题设置弹窗显示状态
  135. @State colorRows: Array<Array<ThemeColorItem>> = chunkArray(SettingPage.THEME_COLOR_LIST, 2);
  136. @State colorGroup: string = "group"
  137. @StorageProp('topRectHeight') topRectHeight: number = px2vp(AppUtil.getStatusBarHeight());
  138. apiDialogController: CustomDialogController = new CustomDialogController({
  139. builder: CustomContentDialog({
  140. primaryTitle: this.apiDialogType === 'lyric' ? '修改歌词API地址' : '修改封面API地址',
  141. contentBuilder: () => {
  142. this.buildApiDialogContent();
  143. },
  144. buttons: [
  145. {
  146. value: '取消',
  147. action: () => {
  148. this.apiDialogController.close();
  149. }
  150. },
  151. {
  152. value: '保存',
  153. action: () => {
  154. if (this.apiDialogType === 'lyric') {
  155. this.lyricApiUrl = this.tempApiUrl.trim()
  156. PreferencesUtil.put('LRC_API', this.lyricApiUrl)
  157. this.getUIContext().getPromptAction().showToast({
  158. message: '保存成功,当前LRC_API:' + this.lyricApiUrl,
  159. duration: 2000,
  160. showMode: promptAction.ToastShowMode.TOP_MOST,
  161. bottom: 85
  162. })
  163. } else {
  164. this.coverApiUrl = this.tempApiUrl.trim()
  165. PreferencesUtil.put('COVER_API', this.coverApiUrl)
  166. this.getUIContext().getPromptAction().showToast({
  167. message: '保存成功,当前COVER_API:' + this.coverApiUrl,
  168. duration: 2000,
  169. showMode: promptAction.ToastShowMode.TOP_MOST,
  170. bottom: 85
  171. })
  172. }
  173. this.apiDialogController.close();
  174. }
  175. }
  176. ]
  177. }),
  178. autoCancel: true,
  179. alignment: DialogAlignment.Center
  180. })
  181. @Builder
  182. buildApiDialogContent() {
  183. Column() {
  184. TextInput({
  185. text: this.tempApiUrl,
  186. placeholder: this.apiDialogType === 'lyric' ? '请输入歌词API地址' : '请输入封面API地址'
  187. })
  188. .onChange((val: string) => {
  189. this.tempApiUrl = val
  190. })
  191. .width('90%')
  192. .height(60)
  193. }
  194. .width('100%')
  195. }
  196. // 组件生命周期
  197. aboutToAppear() {
  198. this.geIDD()
  199. this.topRectHeight = px2vp(AppUtil.getStatusBarHeight());
  200. this.isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN, true)
  201. this.isAutoRatate = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_RATATE, true)
  202. this.isMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_PLAY, true)
  203. this.isMediacodec = PreferencesUtil.getBooleanSync(SettingPage.IS_MIDIACODEC_OPEN, false)
  204. this.isMusicMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_MEMORY_PLAY, false)
  205. this.isMusicBGCover = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_BG_COVER, true)
  206. this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4)
  207. this.isShowSimi = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SIMI, false)
  208. this.isShowFAV = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_FAV, true)
  209. this.isShowHistory = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HISTORY, true)
  210. this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false)
  211. this.customizeBgPath = PreferencesUtil.getStringSync(SettingPage.IS_CUSTOMIZE_BG_PATH, '')
  212. this.isGridMusic = PreferencesUtil.getBooleanSync(SettingPage.IS_GRID_MUSIC, true)
  213. this.isScrollHide = PreferencesUtil.getBooleanSync(SettingPage.IS_SCROLL_HIDE, false)
  214. this.isSameTimePlay = PreferencesUtil.getBooleanSync(SettingPage.IS_SAMETIME_PLAY, false)
  215. this.isSavePlayMode = PreferencesUtil.getBooleanSync(SettingPage.iS_SAVE_PLAY_MODE, true)
  216. this.blurValue = PreferencesUtil.getNumberSync(SettingPage.CUSTOMIZE_BG_BLUR, 0)
  217. this.bgBrightness = PreferencesUtil.getNumberSync(SettingPage.BG_BRIGHTNESS, 0)
  218. this.isStartAutoPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_START_AUTO_PLAY, false)
  219. this.isMemoryLastPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_LAST_PLAY, false)
  220. this.twoFingerType = PreferencesUtil.getNumberSync(SettingPage.TWO_FINGER_TYPE, 3)
  221. this.isCircleBtn = PreferencesUtil.getBooleanSync(SettingPage.IS_CIRCLE_BTN, true)
  222. this.isCoverTop = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP, false)
  223. this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, true)
  224. this.isShowAllBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_ALLBAR, true)
  225. this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, true)
  226. this.isShowSingleLineLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SLLYRIC, false)
  227. this.isCoverTopBig = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP_BIG, false)
  228. this.longPressSpeed = PreferencesUtil.getNumberSync(SettingPage.LONG_PRESS_SPEED, 3)
  229. this.isShowHeader = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HEADER, true)
  230. this.isCoverRectangle = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_RECTANGLE, true)
  231. this.isPlayListBgGrass = PreferencesUtil.getBooleanSync(SettingPage.IS_PLAYLIST_BG_GRASS, true)
  232. this.isSwipe = PreferencesUtil.getBooleanSync(SettingPage.IS_SWIPE, true)
  233. this.is_auto_hide_progress = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_HIDE_PROGRESS, false)
  234. this.openSkipSongAnimate = PreferencesUtil.getBooleanSync(SettingPage.OPEN_SKIPSONG_ANIMATE, true)
  235. // 只用 themeMode 控制主题
  236. this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0)
  237. this.applyThemeMode(this.themeMode)
  238. let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  239. AppStorage.setOrCreate('themeColor', themeColor);
  240. this.themeColor = themeColor;
  241. }
  242. // 监听颜色模式变化
  243. onColorModeChange(): void {
  244. this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
  245. AppStorage.setOrCreate('isDarkMode', this.isDarkMode);
  246. }
  247. // 组件生命周期
  248. aboutToDisappear() {
  249. // 无需处理apiDialogController
  250. }
  251. applyThemeMode(mode: number) {
  252. let colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
  253. if (mode === 1) {
  254. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
  255. } else if (mode === 2) {
  256. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK
  257. }
  258. AppStorage.setOrCreate('currentColorMode', colorMode)
  259. AppStorage.setOrCreate('isDarkMode', colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
  260. PreferencesUtil.putSync(SettingPage.THEME_MODE, mode)
  261. AppStorage.setOrCreate('themeMode', mode)
  262. // 只有强制浅色/深色时才主动设置
  263. const context = getContext(this) as common.UIAbilityContext
  264. context.getApplicationContext().setColorMode(colorMode)
  265. }
  266. @Builder
  267. pickerBuilder() {
  268. Column({ space: 20 }) {
  269. HSBColorPicker({
  270. color: this.customColor,
  271. radius: 8,
  272. onChange: (value: string) => {
  273. this.customColor = value
  274. }
  275. })
  276. .layoutWeight(1)
  277. .padding(15)
  278. Row({ space: 10 }) {
  279. Button('取消')
  280. .stateEffect(true)
  281. .backgroundColor(this.themeColor)
  282. .onClick(() => {
  283. this.showColorPicker = false
  284. })
  285. Button('确定')
  286. .stateEffect(true)
  287. .backgroundColor(this.themeColor)
  288. .onClick(() => {
  289. this.themeColor = this.customColor
  290. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, this.customColor)
  291. AppStorage.setOrCreate('themeColor', this.customColor)
  292. this.sendChangeEvent()
  293. this.showColorPicker = false
  294. })
  295. }
  296. }
  297. .padding(20)
  298. .width('80%')
  299. .height(300)
  300. }
  301. @Builder
  302. themeSheetBuilder() {
  303. Column() {
  304. // 颜色模式分组卡片
  305. Column() {
  306. Row() {
  307. Row() {
  308. Image($r('app.media.theme'))
  309. .width(20)
  310. .height(20)
  311. .fillColor(this.themeColor)
  312. Text('颜色模式')
  313. .fontSize(15)
  314. .margin({ left: 6 })
  315. .fontWeight(500)
  316. }
  317. .layoutWeight(1)
  318. Blank()
  319. Row() {
  320. ForEach(['自动', '日间', '夜间'], (item: string, idx: number) => {
  321. Column() {
  322. Radio({
  323. value: idx.toString(),
  324. group: this.colorGroup,
  325. })
  326. .checked(this.themeMode === idx)
  327. .radioStyle({
  328. checkedBackgroundColor: this.themeColor
  329. })
  330. .margin({ left: 3, right: 3 })
  331. .onClick(() => {
  332. this.themeMode = idx
  333. this.applyThemeMode(idx)
  334. this.sendChangeEvent()
  335. })
  336. Text(item)
  337. .fontSize(15)
  338. .fontColor($r('app.color.text_color'))
  339. .margin({ top: 6 })
  340. .onClick(() => {
  341. this.themeMode = idx
  342. this.applyThemeMode(idx)
  343. this.sendChangeEvent()
  344. })
  345. }
  346. .alignItems(HorizontalAlign.Center)
  347. .margin({ left: 12, right: 12 })
  348. })
  349. }
  350. .margin({ left: 12, right: 12 })
  351. }
  352. }
  353. .backgroundColor($r('app.color.settings_background_main'))
  354. .borderRadius(18)
  355. .border({ width: 1, color: '#F0F0F0' })
  356. .shadow({
  357. radius: 12,
  358. color: 0x11000000,
  359. offsetX: 0,
  360. offsetY: 2
  361. })
  362. .margin({
  363. left: 0,
  364. right: 0,
  365. bottom: 20
  366. })
  367. .padding({
  368. top: 18,
  369. bottom: 18,
  370. left: 20,
  371. right: 20
  372. })
  373. .width('90%')
  374. // 主题色分组卡片
  375. Column() {
  376. Row() {
  377. Image($r('app.media.theme'))
  378. .width(20)
  379. .height(20)
  380. .fillColor(this.themeColor)
  381. Text('主题色')
  382. .fontSize(15)
  383. .fontWeight(500)
  384. .margin({ left: 8 })
  385. .layoutWeight(1)
  386. }
  387. .margin({ left: 20, top: 12 })
  388. Row() {
  389. Column() {
  390. ForEach(this.colorRows, (row: Array<ThemeColorItem>, rowIdx: number) => {
  391. Row() {
  392. ForEach(row, (item: ThemeColorItem, colIdx: number) => {
  393. Button() {
  394. Row() {
  395. Blank()
  396. .width(22)
  397. .height(22)
  398. .backgroundColor(item.name === '自定义' && this.isCustomThemeColor() ? this.themeColor :
  399. item.color)
  400. .border({ width: 2, color: $r('app.color.text_color') })
  401. .borderRadius(11)
  402. Text(item.name)
  403. .fontSize(15)
  404. .fontColor($r('app.color.text_color'))
  405. .margin({ left: 10 })
  406. // Text(item.isVip?'VIP':"Free")
  407. // .fontSize(10)
  408. // .fontColor(item.isVip?'#FFD700':"#000000") // 金色
  409. // .backgroundColor('#FFF9E3')
  410. // .borderRadius(6)
  411. // .padding({ left: 4, right: 4, top: 1, bottom: 1 })
  412. // .margin({ left: 4 })
  413. }
  414. .alignItems(VerticalAlign.Center)
  415. .justifyContent(FlexAlign.Start)
  416. .layoutWeight(1)
  417. }
  418. .height(40)
  419. .layoutWeight(1)
  420. .backgroundColor(
  421. (item.name === '自定义' && this.isCustomThemeColor()) || this.themeColor === item.color
  422. ? this.themeColor
  423. : $r('app.color.settings_background_main')
  424. )
  425. .borderRadius(20)
  426. .onClick(() => {
  427. if (item.isVip) {
  428. if (!Utility.isNoble()) {
  429. this.showVipDialog();
  430. return;
  431. }
  432. }
  433. if (item.name === '自定义') {
  434. this.showColorPicker = true
  435. } else {
  436. this.themeColor = item.color
  437. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, item.color)
  438. AppStorage.setOrCreate('themeColor', item.color)
  439. this.sendChangeEvent()
  440. }
  441. })
  442. .margin({ right: colIdx === 0 ? '4%' : 20, bottom: 10, left: 20 })
  443. })
  444. }
  445. .justifyContent(FlexAlign.Start)
  446. })
  447. }
  448. .margin({ left: 12, right: 12, top: 12 })
  449. }
  450. }
  451. .width('90%')
  452. .backgroundColor($r('app.color.settings_background_main'))
  453. .borderRadius(18)
  454. .border({ width: 1, color: '#F0F0F0' })
  455. .shadow({
  456. radius: 12,
  457. color: 0x11000000,
  458. offsetX: 0,
  459. offsetY: 2
  460. })
  461. .margin({
  462. left: 0,
  463. right: 0,
  464. bottom: 18
  465. })
  466. .padding({
  467. top: 18,
  468. bottom: 18,
  469. left: 0,
  470. right: 0
  471. })
  472. .bindPopup(this.showColorPicker, {
  473. builder: this.pickerBuilder(),
  474. placement: Placement.Top,
  475. mask: { color: '#33000000' },
  476. enableArrow: false, //是否显示箭头
  477. showInSubWindow: false,
  478. onStateChange: (e) => {
  479. if (!e.isVisible) {
  480. this.showColorPicker = false
  481. }
  482. }
  483. })
  484. // 主题色自定义弹窗
  485. }
  486. .padding({
  487. top: 8,
  488. bottom: 8,
  489. left: 15,
  490. right: 15
  491. })
  492. .width('100%')
  493. .backgroundColor(Color.Transparent)
  494. .borderRadius(24)
  495. }
  496. build() {
  497. Column() {
  498. Column() {
  499. Line().width('100%').height('100%')
  500. }
  501. .height(this.topRectHeight)
  502. .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  503. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  504. // 自定义标题栏
  505. Stack() {
  506. // 居中标题
  507. Text('通用设置')
  508. .fontSize(20)
  509. .fontColor(Color.White)
  510. .align(Alignment.Center)
  511. // 左侧返回按钮
  512. Row() {
  513. Image($r('app.media.menu'))
  514. .width(26)
  515. .height(26)
  516. .margin({ left: 12, right: 8 })
  517. .onClick(() => {
  518. animateTo({ duration: 555 }, () => {
  519. // 动画闭包内控制Image组件的出现和消失
  520. this.isShowDrawer = !this.isShowDrawer
  521. this.offsetX = 0
  522. })
  523. })
  524. Blank().flexGrow(1)
  525. Blank().width(32)
  526. }
  527. .height(48)
  528. .width('100%')
  529. .alignItems(VerticalAlign.Center)
  530. }
  531. .height(48)
  532. .width('100%')
  533. .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  534. Scroll() {
  535. Column() {
  536. // 主题设置分组
  537. Column() {
  538. Row() {
  539. Text('个性化')
  540. .margin({ left: 18, right: 20 })
  541. .fontSize(16)
  542. .fontColor(Color.Gray)
  543. .fontWeight(480)
  544. .layoutWeight(1)
  545. }
  546. .height(48)
  547. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  548. // 主题设置弹框入口
  549. Button({ type: ButtonType.Normal, stateEffect: true }) {
  550. Row() {
  551. Text('主题设置')
  552. .margin({ left: 18 })
  553. .fontSize(15)
  554. .fontColor(Color.Gray)
  555. .fontWeight(480)
  556. .layoutWeight(1)
  557. Image($r('app.media.arrow_right'))
  558. .width(22)
  559. .height(22)
  560. .margin({ right: 18 })
  561. }
  562. }
  563. .backgroundColor(Color.Transparent)
  564. .height(55)
  565. .clickEffect({ level: ClickEffectLevel.HEAVY })
  566. .onClick(() => {
  567. this.showColorPicker = false;
  568. this.isThemeSheet = true;
  569. this.customColor = this.themeColor;
  570. })
  571. .bindSheet($$this.isThemeSheet, this.themeSheetBuilder(), {
  572. height: '95%',
  573. dragBar: true,
  574. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  575. showClose: true,
  576. blurStyle: BlurStyle.Thin,
  577. backgroundColor: Color.Transparent,
  578. title: { title: '主题设置' },
  579. shouldDismiss: (SheetDismiss: SheetDismiss) => {
  580. SheetDismiss.dismiss();
  581. this.showColorPicker = false;
  582. }
  583. })
  584. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  585. Button({ type: ButtonType.Normal, stateEffect: true }) {
  586. Row() {
  587. Text('自定义背景')
  588. .margin({ left: 18 })
  589. .fontSize(15)
  590. .fontColor(Color.Gray)
  591. .fontWeight(480)
  592. .layoutWeight(1)
  593. .bindSheet($$this.isCustomizeBgSheet, this.customizeBgSheet(), {
  594. height: '95%',
  595. dragBar: true,
  596. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  597. showClose: true,
  598. blurStyle: BlurStyle.Thin,
  599. backgroundColor: Color.Transparent,
  600. title: { title: '自定义背景' }
  601. })
  602. Blank()
  603. // 右侧箭头
  604. Image($r('app.media.arrow_right'))
  605. .width(22)
  606. .height(22)
  607. .margin({ left: 20, right: 20 })
  608. .align(Alignment.Center)
  609. }
  610. }
  611. .clickEffect({ level: ClickEffectLevel.HEAVY })
  612. .height(55)
  613. .onClick(() => {
  614. if (!Utility.isNoble()) {
  615. this.showVipDialog();
  616. return;
  617. }
  618. this.isCustomizeBgSheet = !this.isCustomizeBgSheet;
  619. })
  620. .backgroundColor(Color.Transparent)
  621. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  622. // 滚动隐藏'
  623. Row() {
  624. Text('滚动隐藏')
  625. .margin({ left: 18 })
  626. .fontSize(15)
  627. .fontColor(Color.Gray)
  628. .fontWeight(480)
  629. .layoutWeight(1)
  630. Toggle({ type: ToggleType.Switch, isOn: this.isScrollHide })
  631. .selectedColor(this.themeColor)
  632. .switchPointColor(Color.White)
  633. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  634. .margin({ right: 18 })
  635. .onChange((checked: boolean) => {
  636. this.isScrollHide = checked;
  637. PreferencesUtil.put(SettingPage.IS_SCROLL_HIDE, this.isScrollHide)
  638. this.sendChangeEvent()
  639. })
  640. .width(50)
  641. .height(30);
  642. }
  643. .height(55)
  644. .visibility(Visibility.None)
  645. .clickEffect({ level: ClickEffectLevel.HEAVY })
  646. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  647. .visibility(Visibility.None)
  648. // 网格布局
  649. Row() {
  650. Text('网格模式')
  651. .margin({ left: 18 })
  652. .fontSize(15)
  653. .fontColor(Color.Gray)
  654. .fontWeight(480)
  655. .layoutWeight(1)
  656. Toggle({ type: ToggleType.Switch, isOn: this.isGridMusic })
  657. .selectedColor(this.themeColor)
  658. .switchPointColor(Color.White)
  659. .margin({ right: 18 })
  660. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  661. .onChange((checked: boolean) => {
  662. this.isGridMusic = checked;
  663. PreferencesUtil.put(SettingPage.IS_GRID_MUSIC, this.isGridMusic)
  664. this.sendChangeEvent()
  665. })
  666. .width(50)
  667. .height(30);
  668. }
  669. .height(55)
  670. .clickEffect({ level: ClickEffectLevel.HEAVY })
  671. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  672. // 封面方形
  673. Row() {
  674. Text('封面方形')
  675. .margin({ left: 18 })
  676. .fontSize(15)
  677. .fontColor(Color.Gray)
  678. .fontWeight(480)
  679. .layoutWeight(1)
  680. Toggle({ type: ToggleType.Switch, isOn: this.isCoverRectangle })
  681. .selectedColor(this.themeColor)
  682. .switchPointColor(Color.White)
  683. .margin({ right: 18 })
  684. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  685. .onChange((checked: boolean) => {
  686. this.isCoverRectangle = checked;
  687. PreferencesUtil.put(SettingPage.IS_COVER_RECTANGLE, this.isCoverRectangle)
  688. this.sendChangeEvent()
  689. })
  690. .width(50)
  691. .height(30);
  692. }
  693. .height(55)
  694. .clickEffect({ level: ClickEffectLevel.HEAVY })
  695. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  696. //播放列表透明
  697. Row() {
  698. Text('播放列表背景透明')
  699. .margin({ left: 18 })
  700. .fontSize(15)
  701. .fontColor(Color.Gray)
  702. .fontWeight(480)
  703. .layoutWeight(1)
  704. Toggle({ type: ToggleType.Switch, isOn: this.isPlayListBgGrass })
  705. .selectedColor(this.themeColor)
  706. .switchPointColor(Color.White)
  707. .margin({ right: 18 })
  708. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  709. .onChange((checked: boolean) => {
  710. this.isPlayListBgGrass = checked;
  711. PreferencesUtil.put(SettingPage.IS_PLAYLIST_BG_GRASS, this.isPlayListBgGrass)
  712. this.sendChangeEvent()
  713. })
  714. .width(50)
  715. .height(30);
  716. }
  717. .height(55)
  718. .clickEffect({ level: ClickEffectLevel.HEAVY })
  719. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  720. // 网格封面大
  721. Row() {
  722. Text('列表封面大小')
  723. .margin({ left: 18 })
  724. .fontSize(15)
  725. .fontColor(Color.Gray)
  726. .fontWeight(480)
  727. .layoutWeight(1)
  728. Select([
  729. { value: CommonConstants.TWO_FINGER_TYPE[0] },
  730. { value: CommonConstants.TWO_FINGER_TYPE[1] },
  731. { value: CommonConstants.TWO_FINGER_TYPE[2] }])
  732. .font({ size: 15, weight: FontWeight.Medium })
  733. .fontColor(Color.Gray)
  734. .margin({ right: 18 })
  735. .selected(this.twoFingerType - 1)
  736. .value(CommonConstants.TWO_FINGER_TYPE[this.twoFingerType-1])
  737. .onSelect(async (_index: number, text?: string | undefined) => {
  738. _index++;
  739. this.twoFingerType = _index
  740. PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE, this.twoFingerType)
  741. this.sendChangeEvent()
  742. })
  743. }
  744. .height(55)
  745. .clickEffect({ level: ClickEffectLevel.HEAVY })
  746. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  747. // 封面顶部
  748. Row() {
  749. Text('封面顶部')
  750. .margin({ left: 18 })
  751. .fontSize(15)
  752. .fontColor(Color.Gray)
  753. .fontWeight(480)
  754. .layoutWeight(1)
  755. Toggle({ type: ToggleType.Switch, isOn: this.isCoverTop })
  756. .selectedColor(this.themeColor)
  757. .switchPointColor(Color.White)
  758. .margin({ right: 18 })
  759. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  760. .onChange((checked: boolean) => {
  761. this.isCoverTop = checked;
  762. PreferencesUtil.put(SettingPage.IS_COVER_TOP, this.isCoverTop)
  763. this.sendChangeEvent()
  764. })
  765. .width(50)
  766. .height(30);
  767. }
  768. .height(55)
  769. .clickEffect({ level: ClickEffectLevel.HEAVY })
  770. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  771. .opacity(this.isCoverTop ? 1 : 0)
  772. .visibility(this.isCoverTop ? Visibility.Visible : Visibility.None)
  773. .animation({
  774. duration: 500,
  775. curve: 'ease-in-out' // 可选动画曲线
  776. })
  777. // 封面顶部
  778. Row() {
  779. Text('顶部大封面')
  780. .margin({ left: 18 })
  781. .fontSize(15)
  782. .fontColor(Color.Gray)
  783. .fontWeight(480)
  784. .layoutWeight(1)
  785. Toggle({ type: ToggleType.Switch, isOn: this.isCoverTopBig })
  786. .selectedColor(this.themeColor)
  787. .switchPointColor(Color.White)
  788. .margin({ right: 18 })
  789. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  790. .onChange((checked: boolean) => {
  791. this.isCoverTopBig = checked;
  792. if(this.isCoverTopBig){
  793. ToastUtil.showToast('启动该开关部分设备封面太大导致和音乐控制重叠!')
  794. }
  795. PreferencesUtil.put(SettingPage.IS_COVER_TOP_BIG, this.isCoverTopBig)
  796. this.sendChangeEvent()
  797. })
  798. .width(50)
  799. .height(30);
  800. }
  801. .height(55)
  802. .clickEffect({ level: ClickEffectLevel.HEAVY })
  803. .opacity(this.isCoverTop ? 1 : 0)
  804. .visibility(this.isCoverTop ? Visibility.Visible : Visibility.None)
  805. .animation({
  806. duration: 500,
  807. curve: 'ease-in-out' // 可选动画曲线
  808. })
  809. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  810. // 切歌动画效果
  811. Row() {
  812. Text('切歌动画效果')
  813. .margin({ left: 18 })
  814. .fontSize(15)
  815. .fontColor(Color.Gray)
  816. .fontWeight(480)
  817. .layoutWeight(1)
  818. Toggle({ type: ToggleType.Switch, isOn: this.openSkipSongAnimate })
  819. .selectedColor(this.themeColor)
  820. .switchPointColor(Color.White)
  821. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  822. .margin({ right: 18 })
  823. .onChange((checked: boolean) => {
  824. this.openSkipSongAnimate = checked;
  825. PreferencesUtil.put(SettingPage.OPEN_SKIPSONG_ANIMATE, this.openSkipSongAnimate)
  826. this.sendChangeEvent()
  827. })
  828. .width(50)
  829. .height(30);
  830. }
  831. .height(55)
  832. .clickEffect({ level: ClickEffectLevel.HEAVY })
  833. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  834. // 圆形播放按钮
  835. Row() {
  836. Text('圆形播放按钮')
  837. .margin({ left: 18 })
  838. .fontSize(15)
  839. .fontColor(Color.Gray)
  840. .fontWeight(480)
  841. .layoutWeight(1)
  842. Toggle({ type: ToggleType.Switch, isOn: this.isCircleBtn })
  843. .selectedColor(this.themeColor)
  844. .switchPointColor(Color.White)
  845. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  846. .margin({ right: 18 })
  847. .onChange((checked: boolean) => {
  848. this.isCircleBtn = checked;
  849. PreferencesUtil.put(SettingPage.IS_CIRCLE_BTN, this.isCircleBtn)
  850. this.sendChangeEvent()
  851. })
  852. .width(50)
  853. .height(30);
  854. }
  855. .height(55)
  856. .clickEffect({ level: ClickEffectLevel.HEAVY })
  857. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  858. }
  859. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  860. .animation({ duration: 500, curve: Curve.Ease, delay: 200 }))
  861. .backgroundColor($r('app.color.settings_background_main'))
  862. .borderRadius(20)
  863. .margin({
  864. left: 0,
  865. right: 0,
  866. top: 0,
  867. bottom: 10
  868. })
  869. .padding(0)
  870. // 音频设置分组
  871. Column() {
  872. Row() {
  873. Text('音频设置')
  874. .margin({ left: 18, right: 20 })
  875. .fontSize(16)
  876. .fontColor(Color.Gray)
  877. .fontWeight(480)
  878. .layoutWeight(1)
  879. }
  880. .height(48)
  881. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  882. // 启动时播放
  883. Row() {
  884. Text('启动时播放')
  885. .margin({ left: 18 })
  886. .fontSize(15)
  887. .fontColor(Color.Gray)
  888. .fontWeight(480)
  889. .layoutWeight(1)
  890. Toggle({ type: ToggleType.Switch, isOn: this.isStartAutoPlay })
  891. .selectedColor(this.themeColor)
  892. .switchPointColor(Color.White)
  893. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  894. .margin({ right: 18 })
  895. .onChange((checked: boolean) => {
  896. this.isStartAutoPlay = checked;
  897. PreferencesUtil.put(SettingPage.iS_START_AUTO_PLAY, this.isStartAutoPlay)
  898. })
  899. .width(50)
  900. .height(30);
  901. }
  902. .height(55)
  903. .clickEffect({ level: ClickEffectLevel.HEAVY })
  904. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  905. // 列表是否可左滑
  906. Row() {
  907. Text('列表是否可左滑')
  908. .margin({ left: 18 })
  909. .fontSize(15)
  910. .fontColor(Color.Gray)
  911. .fontWeight(480)
  912. .layoutWeight(1)
  913. Toggle({ type: ToggleType.Switch, isOn: this.isSwipe })
  914. .selectedColor(this.themeColor)
  915. .switchPointColor(Color.White)
  916. .margin({ right: 18 })
  917. .onChange((checked: boolean) => {
  918. this.isSwipe = checked;
  919. PreferencesUtil.put(SettingPage.IS_SWIPE, this.isSwipe)
  920. this.sendChangeEvent()
  921. })
  922. .width(50)
  923. .height(30);
  924. }
  925. .height(55)
  926. .clickEffect({level:ClickEffectLevel.HEAVY})
  927. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  928. // 记住播放进度
  929. Row() {
  930. Text('记住最后一首进度')
  931. .margin({ left: 18 })
  932. .fontSize(15)
  933. .fontColor(Color.Gray)
  934. .fontWeight(480)
  935. .layoutWeight(1)
  936. Toggle({ type: ToggleType.Switch, isOn: this.isMemoryLastPlay })
  937. .selectedColor(this.themeColor)
  938. .switchPointColor(Color.White)
  939. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  940. .margin({ right: 18 })
  941. .onChange((checked: boolean) => {
  942. this.isMemoryLastPlay = checked;
  943. PreferencesUtil.put(SettingPage.iS_MEMORY_LAST_PLAY, this.isMemoryLastPlay)
  944. this.sendChangeEvent()
  945. })
  946. .width(50)
  947. .height(30);
  948. }
  949. .height(55)
  950. .clickEffect({ level: ClickEffectLevel.HEAVY })
  951. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  952. // 记忆播放
  953. Row() {
  954. Text('记忆播放')
  955. .margin({ left: 18 })
  956. .fontSize(15)
  957. .fontColor(Color.Gray)
  958. .fontWeight(480)
  959. .layoutWeight(1)
  960. Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay })
  961. .selectedColor(this.themeColor)
  962. .switchPointColor(Color.White)
  963. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  964. .margin({ right: 18 })
  965. .onChange((checked: boolean) => {
  966. this.isMusicMemoryPlay = checked;
  967. PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay)
  968. this.sendChangeEvent()
  969. })
  970. .width(50)
  971. .height(30);
  972. }
  973. .height(55)
  974. .clickEffect({ level: ClickEffectLevel.HEAVY })
  975. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  976. // 长按默认倍数
  977. Row() {
  978. Text('长按默认倍数')
  979. .margin({ left: 18 })
  980. .fontSize(15)
  981. .fontColor(Color.Gray)
  982. .fontWeight(480)
  983. .layoutWeight(1)
  984. Select([//倍速
  985. { value: '0.25x' },
  986. { value: '0.5x' },
  987. { value: '0.75x' },
  988. { value: '1x' },
  989. { value: '1.25x' },
  990. { value: '1.5x' },
  991. { value: '1.75x' },
  992. { value: '2x' },
  993. { value: '2.5x' },
  994. { value: '3x' }])
  995. .font({ size: 15, weight: FontWeight.Medium })
  996. .fontColor(Color.Gray)
  997. .margin({right:18})
  998. .selected(CommonConstants.video_speed_list.indexOf(this.longPressSpeed))
  999. .value(Utility.optimizedFormat(this.longPressSpeed))
  1000. .onSelect(async (_index: number, text?: string | undefined) => {
  1001. let speed = parseFloat(text?.replace('x', '') || '1');
  1002. if (!CommonConstants.video_speed_list.includes(speed)) {
  1003. speed = 1;
  1004. }
  1005. this.longPressSpeed = speed
  1006. PreferencesUtil.put(SettingPage.LONG_PRESS_SPEED, this.longPressSpeed)
  1007. this.sendChangeEvent()
  1008. })
  1009. }
  1010. .height(55)
  1011. .clickEffect({level:ClickEffectLevel.HEAVY})
  1012. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1013. // 默认排序模式
  1014. Row() {
  1015. Text('默认排序模式')
  1016. .margin({ left: 18 })
  1017. .fontSize(15)
  1018. .fontColor(Color.Gray)
  1019. .fontWeight(480)
  1020. .layoutWeight(1)
  1021. Select([
  1022. { value: CommonConstants.SORT_ARRAY[0] },
  1023. { value: CommonConstants.SORT_ARRAY[1] },
  1024. { value: CommonConstants.SORT_ARRAY[2] },
  1025. { value: CommonConstants.SORT_ARRAY[3] },
  1026. { value: CommonConstants.SORT_ARRAY[4] },
  1027. { value: CommonConstants.SORT_ARRAY[5] },
  1028. { value: CommonConstants.SORT_ARRAY[6] },
  1029. { value: CommonConstants.SORT_ARRAY[7] }])
  1030. .font({ size: 15, weight: FontWeight.Medium })
  1031. .fontColor(Color.Gray)
  1032. .margin({ right: 18 })
  1033. .selected(this.sortType)
  1034. .value(CommonConstants.SORT_ARRAY[this.sortType])
  1035. .onSelect(async (_index: number, text?: string | undefined) => {
  1036. this.sortType = _index
  1037. PreferencesUtil.put(SettingPage.SORT_TYPE, this.sortType)
  1038. this.sendChangeEvent()
  1039. })
  1040. }
  1041. .height(55)
  1042. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1043. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1044. // 保存播放模式
  1045. Row() {
  1046. Text('保存播放模式')
  1047. .margin({ left: 18 })
  1048. .fontSize(15)
  1049. .fontColor(Color.Gray)
  1050. .fontWeight(480)
  1051. .layoutWeight(1)
  1052. Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode })
  1053. .selectedColor(this.themeColor)
  1054. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1055. .switchPointColor(Color.White)
  1056. .margin({ right: 18 })
  1057. .onChange((checked: boolean) => {
  1058. this.isSavePlayMode = checked;
  1059. PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode)
  1060. })
  1061. .width(50)
  1062. .height(30);
  1063. }
  1064. .height(55)
  1065. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1066. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1067. .visibility(Visibility.None)
  1068. Row() {
  1069. Text('与其他应用同时播放')
  1070. .margin({ left: 18 })
  1071. .fontSize(15)
  1072. .fontColor(Color.Gray)
  1073. .fontWeight(480)
  1074. .layoutWeight(1)
  1075. Toggle({ type: ToggleType.Switch, isOn: this.isSameTimePlay })
  1076. .selectedColor(this.themeColor)
  1077. .switchPointColor(Color.White)
  1078. .margin({ right: 18 })
  1079. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1080. .onChange((checked: boolean) => {
  1081. this.isSameTimePlay = checked;
  1082. PreferencesUtil.put(SettingPage.IS_SAMETIME_PLAY, this.isSameTimePlay)
  1083. })
  1084. .width(50)
  1085. .height(30);
  1086. }
  1087. .height(55).clickEffect({ level: ClickEffectLevel.HEAVY })
  1088. .visibility(Visibility.None)
  1089. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1090. // 播放背景随音乐封面
  1091. Row() {
  1092. Text('播放背景随音乐封面')
  1093. .margin({ left: 18 })
  1094. .fontSize(15)
  1095. .fontColor(Color.Gray)
  1096. .fontWeight(480)
  1097. .layoutWeight(1)
  1098. Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover })
  1099. .selectedColor(this.themeColor)
  1100. .switchPointColor(Color.White)
  1101. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1102. .margin({ right: 18 })
  1103. .onChange((checked: boolean) => {
  1104. this.isMusicBGCover = checked;
  1105. PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover)
  1106. })
  1107. .width(50)
  1108. .height(30);
  1109. }
  1110. .height(55)
  1111. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1112. }
  1113. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  1114. .animation({ duration: 500, curve: Curve.Ease, delay: 400 }))
  1115. .backgroundColor($r('app.color.settings_background_main'))
  1116. .borderRadius(20)
  1117. .margin({
  1118. left: 0,
  1119. right: 0,
  1120. top: 10,
  1121. bottom: 10
  1122. })
  1123. .padding(0)
  1124. // API设置分组
  1125. this.apiBuilder()
  1126. //设置教程
  1127. this.jcBuilder()
  1128. //显示与隐藏设置
  1129. this.xsBuilder()
  1130. //空白
  1131. Column() {
  1132. Blank()
  1133. .height(88)
  1134. }.height(88)
  1135. }
  1136. .margin({
  1137. left: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  1138. right: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  1139. top: 20,
  1140. bottom: 20
  1141. })
  1142. .justifyContent(FlexAlign.Start)
  1143. }
  1144. .scrollBar(BarState.Auto)
  1145. .width('100%')
  1146. .margin({ bottom: 10 })
  1147. .backgroundColor($r('app.color.settings_background'))
  1148. }
  1149. .layoutWeight(1)
  1150. .height('100%')
  1151. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  1152. }
  1153. @Builder
  1154. xsBuilder() {
  1155. // 显示和隐藏分组
  1156. Column() {
  1157. Row() {
  1158. Text('显示隐藏')
  1159. .margin({ left: 18, right: 20 })
  1160. .fontSize(16)
  1161. .fontColor(Color.Gray)
  1162. .fontWeight(480)
  1163. .layoutWeight(1)
  1164. }
  1165. .onClick(() => {
  1166. ToastUtil.showToast(this.appIdentifier)
  1167. PreferencesUtil.putSync('isShowWX',true)
  1168. })
  1169. .height(48)
  1170. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1171. Row() {
  1172. Text('显示分类导航')
  1173. .margin({ left: 18 })
  1174. .fontSize(15)
  1175. .fontColor(Color.Gray)
  1176. .fontWeight(480)
  1177. .layoutWeight(1)
  1178. Toggle({ type: ToggleType.Switch, isOn: this.isShowTitleBar })
  1179. .selectedColor(this.themeColor)
  1180. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1181. .switchPointColor(Color.White)
  1182. .margin({ right: 18 })
  1183. .onChange((checked: boolean) => {
  1184. this.isShowTitleBar = checked;
  1185. PreferencesUtil.put(SettingPage.IS_SHOW_TITLTBAR, this.isShowTitleBar)
  1186. this.sendChangeEvent()
  1187. })
  1188. .width(50)
  1189. .height(30);
  1190. }
  1191. .height(55)
  1192. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1193. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1194. Row() {
  1195. Text('显示播放全部')
  1196. .margin({ left: 18 })
  1197. .fontSize(15)
  1198. .fontColor(Color.Gray)
  1199. .fontWeight(480)
  1200. .layoutWeight(1)
  1201. Toggle({ type: ToggleType.Switch, isOn: this.isShowAllBar })
  1202. .selectedColor(this.themeColor)
  1203. .switchPointColor(Color.White)
  1204. .margin({ right: 18 })
  1205. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1206. .onChange((checked: boolean) => {
  1207. this.isShowAllBar = checked;
  1208. PreferencesUtil.put(SettingPage.IS_SHOW_ALLBAR, this.isShowAllBar)
  1209. this.sendChangeEvent()
  1210. })
  1211. .width(50)
  1212. .height(30);
  1213. }
  1214. .height(55)
  1215. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1216. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1217. // 显示私密音频
  1218. Row() {
  1219. Text('显示私密音频')
  1220. .margin({ left: 18 })
  1221. .fontSize(15)
  1222. .fontColor(Color.Gray)
  1223. .fontWeight(480)
  1224. .layoutWeight(1)
  1225. Toggle({ type: ToggleType.Switch, isOn: this.isShowSimi })
  1226. .selectedColor(this.themeColor)
  1227. .switchPointColor(Color.White)
  1228. .margin({ right: 18 })
  1229. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1230. .onChange((checked: boolean) => {
  1231. this.isShowSimi = checked;
  1232. PreferencesUtil.put(SettingPage.IS_SHOW_SIMI, this.isShowSimi)
  1233. this.sendChangeEvent()
  1234. })
  1235. .width(50)
  1236. .height(30);
  1237. }
  1238. .height(55)
  1239. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1240. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1241. // 播放页单行歌词
  1242. Row() {
  1243. Text('播放页单行歌词')
  1244. .margin({ left: 18 })
  1245. .fontSize(15)
  1246. .fontColor(Color.Gray)
  1247. .fontWeight(480)
  1248. .layoutWeight(1)
  1249. Toggle({ type: ToggleType.Switch, isOn: this.isShowSingleLineLyric })
  1250. .selectedColor(this.themeColor)
  1251. .switchPointColor(Color.White)
  1252. .margin({ right: 18 })
  1253. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1254. .onChange((checked: boolean) => {
  1255. this.isShowSingleLineLyric = checked;
  1256. PreferencesUtil.put(SettingPage.IS_SHOW_SLLYRIC, this.isShowSingleLineLyric)
  1257. this.sendChangeEvent()
  1258. })
  1259. .width(50)
  1260. .height(30);
  1261. }
  1262. .height(55)
  1263. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1264. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1265. // 二级菜单新风格
  1266. Row() {
  1267. Text('二级菜单新风格')
  1268. .margin({ left: 18 })
  1269. .fontSize(15)
  1270. .fontColor(Color.Gray)
  1271. .fontWeight(480)
  1272. .layoutWeight(1)
  1273. Toggle({ type: ToggleType.Switch, isOn: this.isShowHeader })
  1274. .selectedColor(this.themeColor)
  1275. .switchPointColor(Color.White)
  1276. .margin({ right: 18 })
  1277. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1278. .onChange((checked: boolean) => {
  1279. this.isShowHeader = checked;
  1280. PreferencesUtil.put(SettingPage.IS_SHOW_HEADER, this.isShowHeader)
  1281. this.sendChangeEvent()
  1282. })
  1283. .width(50)
  1284. .height(30);
  1285. }
  1286. .height(55)
  1287. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1288. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1289. // 播放页返回键
  1290. Row() {
  1291. Text('显示播放页返回键')
  1292. .margin({ left: 18 })
  1293. .fontSize(15)
  1294. .fontColor(Color.Gray)
  1295. .fontWeight(480)
  1296. .layoutWeight(1)
  1297. Toggle({ type: ToggleType.Switch, isOn: this.isShowPlayPageBack })
  1298. .selectedColor(this.themeColor)
  1299. .switchPointColor(Color.White)
  1300. .margin({ right: 18 })
  1301. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1302. .onChange((checked: boolean) => {
  1303. this.isShowPlayPageBack = checked;
  1304. PreferencesUtil.put(SettingPage.IS_SHOW_PLAYPAGE_BACK, this.isShowPlayPageBack)
  1305. this.sendChangeEvent()
  1306. })
  1307. .width(50)
  1308. .height(30);
  1309. }
  1310. .height(55)
  1311. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1312. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1313. // 自动隐藏进度条两侧的按钮
  1314. Row() {
  1315. Text('自动隐藏进度条两侧的按钮')
  1316. .margin({ left: 18 })
  1317. .fontSize(15)
  1318. .fontColor(Color.Gray)
  1319. .fontWeight(480)
  1320. .layoutWeight(1)
  1321. Toggle({ type: ToggleType.Switch, isOn: this.is_auto_hide_progress })
  1322. .selectedColor(this.themeColor)
  1323. .switchPointColor(Color.White)
  1324. .margin({ right: 18 })
  1325. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1326. .onChange((checked: boolean) => {
  1327. this.is_auto_hide_progress = checked;
  1328. PreferencesUtil.put(SettingPage.IS_AUTO_HIDE_PROGRESS, this.is_auto_hide_progress)
  1329. this.sendChangeEvent()
  1330. })
  1331. .width(50)
  1332. .height(30);
  1333. }
  1334. .height(55)
  1335. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1336. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1337. // 显示我的收藏
  1338. Row() {
  1339. Text('显示我的收藏')
  1340. .margin({ left: 18 })
  1341. .fontSize(15)
  1342. .fontColor(Color.Gray)
  1343. .fontWeight(480)
  1344. .layoutWeight(1)
  1345. Toggle({ type: ToggleType.Switch, isOn: this.isShowFAV })
  1346. .selectedColor(this.themeColor)
  1347. .switchPointColor(Color.White)
  1348. .margin({ right: 18 })
  1349. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1350. .onChange((checked: boolean) => {
  1351. this.isShowFAV = checked;
  1352. PreferencesUtil.put(SettingPage.IS_SHOW_FAV, this.isShowFAV)
  1353. this.sendChangeEvent()
  1354. })
  1355. .width(50)
  1356. .height(30);
  1357. }
  1358. .height(55)
  1359. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1360. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1361. // 显示最近播放
  1362. Row() {
  1363. Text('显示最近播放')
  1364. .margin({ left: 18 })
  1365. .fontSize(15)
  1366. .fontColor(Color.Gray)
  1367. .fontWeight(480)
  1368. .layoutWeight(1)
  1369. Toggle({ type: ToggleType.Switch, isOn: this.isShowHistory })
  1370. .selectedColor(this.themeColor)
  1371. .switchPointColor(Color.White)
  1372. .margin({ right: 18 })
  1373. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1374. .onChange((checked: boolean) => {
  1375. this.isShowHistory = checked;
  1376. PreferencesUtil.put(SettingPage.IS_SHOW_HISTORY, this.isShowHistory)
  1377. this.sendChangeEvent()
  1378. })
  1379. .width(50)
  1380. .height(30);
  1381. }
  1382. .height(55)
  1383. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1384. }
  1385. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  1386. .animation({ duration: 500, curve: Curve.Ease, delay: 600 }))
  1387. .backgroundColor($r('app.color.settings_background_main'))
  1388. .borderRadius(20)
  1389. .margin({
  1390. left: 0,
  1391. right: 0,
  1392. top: 10,
  1393. bottom: 20
  1394. })
  1395. .padding(0)
  1396. }
  1397. @Builder
  1398. jcBuilder() {
  1399. //设置教程
  1400. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  1401. Column() {
  1402. Row() {
  1403. Text('设置教程:')
  1404. .margin({ left: 18 })
  1405. .fontSize(15)
  1406. .fontColor(Color.Gray)
  1407. .fontWeight(480)
  1408. Text('点击进Q群讨论')
  1409. .margin({ right: 10 })
  1410. .fontSize(15)
  1411. .fontColor(Color.Gray)
  1412. .layoutWeight(1)
  1413. Blank()
  1414. // 右侧箭头
  1415. Image($r('app.media.arrow_right'))
  1416. .width(22)
  1417. .height(22)
  1418. .margin({ left: 20, right: 20 })
  1419. .align(Alignment.Center)
  1420. }
  1421. .height(55)
  1422. }
  1423. }
  1424. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1425. .onClick(() => {
  1426. const qqUrl =
  1427. `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${CommonConstants.QQ_GROUP}&card_type=group&source=external`
  1428. let context = this.getUIContext().getHostContext() as common.UIAbilityContext
  1429. context.openLink(qqUrl, {})
  1430. })
  1431. .backgroundColor($r('app.color.settings_background_main'))
  1432. .borderRadius(15)
  1433. .margin({ top: 0, bottom: 20 })
  1434. .padding(0)
  1435. }
  1436. @Builder
  1437. apiBuilder() {
  1438. // API设置分组
  1439. Column() {
  1440. Row() {
  1441. Text('API设置')
  1442. .margin({ left: 18, right: 20 })
  1443. .fontSize(16)
  1444. .fontColor(Color.Gray)
  1445. .fontWeight(480)
  1446. .layoutWeight(1)
  1447. }
  1448. .height(48)
  1449. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1450. // 歌词API
  1451. Button({ type: ButtonType.Normal, stateEffect: true }) {
  1452. Row() {
  1453. Text('歌词:')
  1454. .margin({ left: 18, right: 6 })
  1455. .fontSize(15)
  1456. .fontColor(Color.Gray)
  1457. Text(this.lyricApiUrl)
  1458. .margin({ right: 10 })
  1459. .fontSize(15)
  1460. .fontColor(Color.Gray)
  1461. .layoutWeight(1)
  1462. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  1463. .width(20)
  1464. .height(20)
  1465. .margin({ right: 18 })
  1466. }
  1467. }
  1468. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1469. .backgroundColor(Color.Transparent)
  1470. .onClick(() => {
  1471. this.apiDialogType = 'lyric'
  1472. this.tempApiUrl = this.lyricApiUrl
  1473. this.apiDialogController.open()
  1474. })
  1475. .height(55)
  1476. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1477. // 封面API
  1478. Button({ type: ButtonType.Normal, stateEffect: true }) {
  1479. Row() {
  1480. Text('封面:')
  1481. .margin({ left: 18, right: 6 })
  1482. .fontSize(15)
  1483. .fontColor(Color.Gray)
  1484. Text(this.coverApiUrl)
  1485. .margin({ right: 10 })
  1486. .fontSize(15)
  1487. .fontColor(Color.Gray)
  1488. .layoutWeight(1)
  1489. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  1490. .width(20)
  1491. .height(20)
  1492. .margin({ right: 18 })
  1493. }
  1494. }
  1495. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1496. .backgroundColor(Color.Transparent)
  1497. .onClick(() => {
  1498. this.apiDialogType = 'cover'
  1499. this.tempApiUrl = this.coverApiUrl
  1500. this.apiDialogController.open()
  1501. })
  1502. .height(55)
  1503. }
  1504. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  1505. .animation({ duration: 500, curve: Curve.Ease, delay: 600 }))
  1506. .backgroundColor($r('app.color.settings_background_main'))
  1507. .borderRadius(20)
  1508. .margin({
  1509. left: 0,
  1510. right: 0,
  1511. top: 10,
  1512. bottom: 20
  1513. })
  1514. .padding(0)
  1515. }
  1516. //发送广播通知更新UI
  1517. sendChangeEvent() {
  1518. const eventData: emitter.EventData = {};
  1519. emitter.emit({ eventId: 333 }, eventData); // 发送广播通知更新doSwipBack
  1520. }
  1521. goSelectImage() {
  1522. let selectUris: Array<string> = [];
  1523. let photoPicker = new photoAccessHelper.PhotoViewPicker();
  1524. let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  1525. photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
  1526. photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
  1527. photoPicker.select(photoSelectOptions).then(async (photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
  1528. //用一个全局变量存储返回的uri
  1529. selectUris = photoSelectResult.photoUris;
  1530. console.info('photoViewPicker.select to file succeed and uris are:' + selectUris);
  1531. //使用fs.openSync接口,通过uri打开这个文件得到fd
  1532. let file = fileIo.openSync(selectUris[0], fileIo.OpenMode.READ_ONLY);
  1533. console.info('file fd: ' + file.fd);
  1534. const timestamp: number = Math.floor(Date.now() / 1000);
  1535. let name = timestamp + "_homebg"
  1536. let imagePath = this.context.filesDir + FileUtil.separator + name
  1537. imagePath = fileUri.getUriFromPath(imagePath)
  1538. let file2 = fileIo.openSync(imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
  1539. fileIo.copyFileSync(file.fd, file2.fd)
  1540. fileIo.closeSync(file);
  1541. fileIo.closeSync(file2);
  1542. this.customizeBgPath = imagePath
  1543. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG_PATH, this.customizeBgPath)
  1544. this.sendChangeEvent()
  1545. }).catch((err: BusinessError) => {
  1546. console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
  1547. })
  1548. }
  1549. @Builder
  1550. customizeBgSheet() {
  1551. Scroll() {
  1552. Column() {
  1553. this.CustomizeBg()
  1554. }
  1555. }
  1556. .width('100%')
  1557. .height('100%')
  1558. }
  1559. @Builder
  1560. CustomizeBg() {
  1561. Column() {
  1562. Image(this.customizeBgPath)
  1563. .height('42%')
  1564. .alt($r('app.color.white'))
  1565. .objectFit(ImageFit.Contain)
  1566. .borderRadius(20)
  1567. .clip(true)
  1568. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1569. .blur(this.blurValue)
  1570. .brightness(this.bgBrightness + 0.8)
  1571. .margin({ left: 30, right: 30, bottom: 20 })
  1572. Row() {
  1573. Row() {
  1574. Button('选择图片')
  1575. .fontColor(Color.White)
  1576. .fontSize(12)
  1577. .height(48)
  1578. .width(100)
  1579. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1580. .backgroundColor(this.themeColor)
  1581. .stateEffect(true)
  1582. .onClick(async () => {
  1583. this.goSelectImage()
  1584. })
  1585. }
  1586. .height('100%')
  1587. .justifyContent(FlexAlign.Center)
  1588. .layoutWeight(1)
  1589. }
  1590. .width('100%')
  1591. .height(58)
  1592. .margin({ bottom: 20 })
  1593. Column() {
  1594. Row() {
  1595. Text('自定义背景:')
  1596. .margin({ left: 18 })
  1597. .fontSize(15)
  1598. .fontColor($r('app.color.text_color'))
  1599. .fontWeight(480)
  1600. .layoutWeight(1)
  1601. Toggle({ type: ToggleType.Switch, isOn: this.isCustomizeBg })
  1602. .selectedColor(this.themeColor)
  1603. .switchPointColor(Color.White)
  1604. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1605. .margin({ right: 18 })
  1606. .onChange((checked: boolean) => {
  1607. this.isCustomizeBg = checked;
  1608. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG, this.isCustomizeBg)
  1609. this.sendChangeEvent()
  1610. })
  1611. .width(50)
  1612. .height(30);
  1613. }
  1614. .height(55)
  1615. }
  1616. .backgroundColor($r('app.color.settings_background_main'))
  1617. .borderRadius(15)
  1618. .margin({
  1619. left: 30,
  1620. right: 30,
  1621. top: 0,
  1622. bottom: 20
  1623. })
  1624. .padding(0)
  1625. Column() {
  1626. Row() {
  1627. Text('背景模糊:')
  1628. .margin({ left: 18 })
  1629. .fontSize(15)
  1630. .fontColor($r('app.color.text_color'))
  1631. .fontWeight(480)
  1632. Slider({
  1633. value: this.blurValue,
  1634. min: 0,
  1635. max: 100,
  1636. step: 1,
  1637. style: SliderStyle.OutSet
  1638. })
  1639. .blockColor(this.themeColor)
  1640. .trackColor($r('app.color.speed_text_color'))
  1641. .selectedColor($r('app.color.index_background'))
  1642. .trackThickness(8)
  1643. .onChange((value: number) => {
  1644. this.blurValue = value;
  1645. PreferencesUtil.put(SettingPage.CUSTOMIZE_BG_BLUR, this.blurValue)
  1646. this.sendChangeEvent()
  1647. })
  1648. .layoutWeight(1)
  1649. }
  1650. .height(55)
  1651. }
  1652. .backgroundColor($r('app.color.settings_background_main'))
  1653. .borderRadius(15)
  1654. .margin({
  1655. left: 30,
  1656. right: 30,
  1657. top: 0,
  1658. bottom: 20
  1659. })
  1660. .padding(0)
  1661. Column() {
  1662. Row() {
  1663. Text('背景亮度:')
  1664. .margin({ left: 18 })
  1665. .fontSize(15)
  1666. .fontColor($r('app.color.text_color'))
  1667. .fontWeight(480)
  1668. Slider({
  1669. value: this.bgBrightness,
  1670. min: -0.4,
  1671. max: 0.4,
  1672. step: 0.1,
  1673. style: SliderStyle.OutSet
  1674. })
  1675. .blockColor(this.themeColor)
  1676. .trackColor($r('app.color.speed_text_color'))
  1677. .selectedColor($r('app.color.index_background'))
  1678. .trackThickness(8)
  1679. .onChange((value: number) => {
  1680. this.bgBrightness = value;
  1681. PreferencesUtil.put(SettingPage.BG_BRIGHTNESS, this.bgBrightness)
  1682. this.sendChangeEvent()
  1683. })
  1684. .layoutWeight(1)
  1685. }
  1686. .height(55)
  1687. }
  1688. .backgroundColor($r('app.color.settings_background_main'))
  1689. .borderRadius(15)
  1690. .margin({
  1691. left: 30,
  1692. right: 30,
  1693. top: 0,
  1694. bottom: 20
  1695. })
  1696. .padding(0)
  1697. }
  1698. .margin({ bottom: 30 })
  1699. }
  1700. // 判断当前主题色是否为自定义色
  1701. isCustomThemeColor(): boolean {
  1702. for (let i = 0; i < SettingPage.THEME_COLOR_LIST.length - 1; i++) {
  1703. if (SettingPage.THEME_COLOR_LIST[i].color === this.themeColor) {
  1704. return false;
  1705. }
  1706. }
  1707. return true;
  1708. }
  1709. // 会员功能弹窗
  1710. showVipDialog() {
  1711. DialogHelper.showCustomContentDialog({
  1712. dialogId: 'vip',
  1713. title: "友情提示",
  1714. autoCancel: false,
  1715. backCancel: true,
  1716. contentBuilder: () => {
  1717. this.customVipBuilder("该功能需开通会员,非常感谢您的支持!")
  1718. },
  1719. buttons: [],
  1720. })
  1721. }
  1722. @Builder
  1723. customVipBuilder(content: string) {
  1724. Column() {
  1725. Text(content)
  1726. .fontColor(Color.Gray)
  1727. .fontSize(16)
  1728. .alignSelf(ItemAlign.Start)
  1729. .margin({ bottom: 15 })
  1730. Row() {
  1731. Button('取消')
  1732. .fontColor(Color.White)
  1733. .backgroundColor(this.themeColor)
  1734. .height(50)
  1735. .layoutWeight(1)
  1736. .stateEffect(true)
  1737. .margin({ right: 6 })
  1738. .onClick(() => {
  1739. DialogHelper.closeDialog('vip');
  1740. })
  1741. Button('开通')
  1742. .fontColor(Color.White)
  1743. .layoutWeight(1)
  1744. .height(50)
  1745. .backgroundColor(this.themeColor)
  1746. .stateEffect(true)
  1747. .margin({ left: 6 })
  1748. .onClick(() => {
  1749. this.isThemeSheet = false;
  1750. DialogHelper.closeDialog('vip');
  1751. this.mType = 1//跳转到用户中心
  1752. // router.pushUrl({
  1753. // url: 'pages/UserCenter'
  1754. // }, router.RouterMode.Single);
  1755. })
  1756. }
  1757. }
  1758. .width("100%")
  1759. .padding(10)
  1760. }
  1761. @State appIdentifier:string=''
  1762. geIDD() {
  1763. // 获取应用签名等信息示例代码
  1764. let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
  1765. bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
  1766. try {
  1767. bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
  1768. hilog.info(0x0000, 'testTag11', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data));
  1769. let inde = JSON.stringify(data)
  1770. this.appIdentifier = inde.substring(inde.indexOf('appIdentifier'),inde.indexOf('"certificate'))
  1771. hilog.info(0x0000, 'testTag11', 'appIdentifier Data: %{public}s', this.appIdentifier);
  1772. }).catch((err: BusinessError) => {
  1773. hilog.error(0x0000, 'testTag11', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
  1774. });
  1775. } catch (err) {
  1776. let message = (err as BusinessError).message;
  1777. hilog.error(0x0000, 'testTag33', 'getBundleInfoForSelf failed: %{public}s', message);
  1778. }
  1779. }
  1780. }
  1781. // 主题色类型声明
  1782. export interface ThemeColorItem {
  1783. name: string;
  1784. color: string;
  1785. isVip: boolean;
  1786. }
  1787. // 工具函数:将一维数组分成每行2个的二维数组
  1788. function chunkArray<T>(arr: Array<T>, size: number): Array<Array<T>> {
  1789. const result: Array<Array<T>> = [];
  1790. for (let i = 0; i < arr.length; i += size) {
  1791. const row: Array<T> = [];
  1792. for (let j = 0; j < size; j++) {
  1793. if (i + j < arr.length) {
  1794. row.push(arr[i + j]);
  1795. }
  1796. }
  1797. result.push(row);
  1798. }
  1799. return result;
  1800. }