SettingPage.ets 131 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393
  1. import TitleBar from '../view/TitleBar'
  2. import { EqualizerView } from '../view/EqualizerView'
  3. import { promptAction, router } from '@kit.ArkUI'
  4. import { CommonConstants } from '../common/constants/CommonConstants'
  5. import { EventConstants } from '../common/constants/EventConstants'
  6. import { AppUtil, DeviceUtil, DisplayUtil, FileUtil, LogUtil, MD5, PreferencesUtil, ToastUtil } from '@pura/harmony-utils'
  7. import { CustomContentDialog } from '@kit.ArkUI'
  8. import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
  9. import common from '@ohos.app.ability.common';
  10. import { photoAccessHelper } from '@kit.MediaLibraryKit'
  11. import { fileIo, fileUri } from '@kit.CoreFileKit'
  12. import { BusinessError, emitter } from '@kit.BasicServicesKit'
  13. import { BreakpointTypeEnum } from '../common/util/BreakpointSystem'
  14. import { Utility } from '../common/util/Utility'
  15. import { HSBColorPicker } from '@keke/color-picker'
  16. import { DialogHelper } from '@pura/harmony-dialog'
  17. import { bundleManager } from '@kit.AbilityKit'
  18. import { hilog } from '@kit.PerformanceAnalysisKit'
  19. import { SelectItem } from './SelectItem'
  20. import { FastForwardSecondInterface } from './FastForwardSecondInterface'
  21. import { ButtonFancyModifier, ShadowModifier, SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil'
  22. import { CustomizeICON, Icon } from '../view/CustomizeICON'
  23. import { appInfoManager } from '@kit.StoreKit'
  24. import { clearWebDavCacheByAccount, clearWebDavCaches, clearAllRemoteCaches } from '../common/network/RemoteSongCache';
  25. import { RemoteDriveManager } from '../common/util/RemoteDriveManager';
  26. import { LogCollector } from '../common/util/LogCollector';
  27. import { Uploader, UploadConfig } from '../common/network/Uploader';
  28. import { UpTokenUtil } from '../common/util/UpTokenUtil';
  29. import { ServerLogUtil } from '../common/util/ServerLogUtil';
  30. import { BackupManageView } from '../view/BackupManageView';
  31. import { audio } from '@kit.AudioKit'
  32. @Preview
  33. // @Entry
  34. @Component
  35. export struct SettingPage {
  36. @State showFindLocation: boolean = true
  37. @State showZMIndex: boolean = false //是否右侧显示字母索引
  38. @State autoHideTitle: boolean = true //滚动自动隐藏标题栏
  39. @State isNoJumpToHome: boolean = false //网盘播放不跳转首页
  40. @State iconCurrentID: string = 'default';//图标的id
  41. @State iconArray: Array<Icon> = []
  42. @State webdavUploadDuplicateAction: string = 'skip' // WebDAV上传重复文件处理方式
  43. @State webdavUploadAutoClear: boolean = false // WebDAV上传完成后自动清理队列
  44. @State webdavUploadAllowMobile: boolean = false // WebDAV是否允许移动网络上传
  45. @State webdavUploadRetryCount: number = 3 // WebDAV上传失败自动重试次数
  46. @StorageProp('isLandscape') isLandscape: boolean = false;
  47. @State isCustomizeICONSheet: boolean = false //自定义背景界面
  48. @StorageProp('topSafeHeight') topSafeHeight: number = 0;
  49. @State isCopyFileToDownLoad: boolean = false
  50. static readonly IS_COPYFILE_TO_DOWNLOAD: string = 'isCopyFileToDownLoad';
  51. static readonly WEBDAV_UPLOAD_DUPLICATE_ACTION: string = 'webdavUploadDuplicateAction';
  52. static readonly WEBDAV_UPLOAD_AUTO_CLEAR: string = 'webdavUploadAutoClear';
  53. static readonly WEBDAV_UPLOAD_ALLOW_MOBILE: string = 'webdavUploadAllowMobile';
  54. static readonly WEBDAV_UPLOAD_RETRY_COUNT: string = 'webdavUploadRetryCount';
  55. static readonly BLUETOOTH_DISCONNECT_PAUSE: string = 'bluetoothDisconnectPause';
  56. static readonly BLUETOOTH_LYRIC_ENABLED: string = 'bluetoothLyricEnabled';
  57. static readonly BLUETOOTH_LYRIC_MODE: string = 'bluetoothLyricMode';
  58. @State fastForwardSeconds: string = '10'
  59. @State isShowBackFast: boolean = true//快进快退按钮
  60. @State preloadNextSong: boolean = true // 提前缓存下一首
  61. @State bluetoothDisconnectPause: boolean = false // 蓝牙设备断开暂停
  62. @State bluetoothLyricEnabled: boolean = false // 蓝牙歌词显示
  63. @State bluetoothLyricMode: number = 0 // 蓝牙歌词显示模式: 0=歌词在artist, 1=歌词在title
  64. @State isClearingCache: boolean = false
  65. @Consume isShowDrawer: boolean;
  66. @Consume offsetX: number;
  67. @Consume mType: number;
  68. static readonly THEME_MODE: string = 'themeMode';
  69. static readonly SORT_TYPE: string = 'musicSortType';
  70. static readonly IS_BGPLAY_OPEN: string = 'isBgPlayOpen';
  71. static readonly IS_AUTO_RATATE: string = 'isAutoRatate';
  72. static readonly iS_MEMORY_PLAY: string = 'isMemoryPlay';
  73. static readonly IS_MIDIACODEC_OPEN: string = 'isMediacodec';
  74. static readonly iS_MUSIC_MEMORY_PLAY: string = 'isMusicMemoryPlay';
  75. static readonly iS_MUSIC_BG_COVER: string = 'isMusicBGCover';
  76. static readonly iS_SAVE_PLAY_MODE: string = 'isSavePlayMode';
  77. static readonly IS_COVER_RECTANGLE: string = 'isCoverRectangle'; //封面圆形或者方形
  78. static readonly IS_SHOW_SIMI: string = 'isShowSimi';
  79. static readonly IS_SHOW_FAV: string = 'isShowFAV';
  80. static readonly IS_SHOW_HISTORY: string = 'isShowHistory';
  81. static readonly IS_CUSTOMIZE_BG: string = 'is_customize_bg';
  82. static readonly IS_GRID_MUSIC: string = 'is_grid_music';
  83. static readonly IS_CUSTOMIZE_BG_PATH: string = 'is_customize_bg_path';
  84. static readonly IS_SCROLL_HIDE: string = 'isAutoScrollHide';
  85. static readonly IS_SAMETIME_PLAY: string = 'isSameTimePlay';
  86. static readonly CUSTOMIZE_BG_BLUR: string = 'customize_bg_blur';
  87. static readonly BG_BRIGHTNESS: string = 'bg_brightness';
  88. static readonly IS_SHOW_ALLBAR: string = 'IS_SHOW_ALLBAR';
  89. static readonly IS_SHOW_TITLTBAR: string = 'IS_SHOW_TITLTBAR';
  90. static readonly IS_SHOW_PLAYPAGE_BACK: string = 'IS_SHOW_PLAYPAGE_BACK';
  91. static readonly IS_SHOW_SLLYRIC: string = 'IS_SHOW_SLLYRIC';
  92. static readonly IS_ENABLE_WORD_BY_WORD_LYRIC: string = 'IS_ENABLE_WORD_BY_WORD_LYRIC';
  93. static readonly IS_LIGHT_TEXT: string = 'IS_LIGHT_TEXT';
  94. static readonly IS_CIRCLE_BTN: string = 'isCircleBtn';
  95. static readonly IS_COVER_TOP: string = 'IS_COVER_TOP';
  96. static readonly IS_SHOW_HEADER: string = 'IS_SHOW_HEADER';
  97. static readonly IS_COVER_TOP_BIG: string = 'IS_COVER_TOP_BIG';
  98. static readonly LOG_UPLOAD_ENABLED: string = 'logUploadEnabled';
  99. static readonly MEITU_UPLOAD_TOKEN_KEY: string = 'meituUploadToken';
  100. static readonly MEITU_UPLOAD_DOMAIN_KEY: string = 'meituUploadDomain';
  101. static readonly MEITU_AK: string = '7msMIyQ9xOjOwqO9JSPl';
  102. static readonly MEITU_SK: string = 'JU8kLByQ1U1Zgkfni95IC9ttvfv5NLC3qO642R1Z';
  103. static readonly MEITU_BUCKET: string = 'makeup-magic';
  104. static readonly MEITU_DOMAIN: string = 'https://makeup-magic.zone1.meitudata.com';
  105. public static THEME_COLOR_KEY: string = 'THEME_COLOR';
  106. public static TWO_FINGER_TYPE: string = 'twoFingerType';
  107. public static LONG_PRESS_SPEED: string = 'longPressSpeed';
  108. public static IS_PLAYLIST_BG_GRASS: string = 'isPlayListBgGrass';
  109. static readonly IS_SWIPE: string = 'isSwipe'
  110. static readonly IS_AUTO_HIDE_PROGRESS: string = 'IS_AUTO_HIDE_PROGRESS';
  111. public static OPEN_SKIPSONG_ANIMATE: string = 'openSkipSongAnimate';
  112. static readonly IS_PLAYPAGE_SWIPE_NEXT: string = 'isPlayPageSwipeNext';
  113. @State autoParseMusicName: boolean = false
  114. @State defalut_home_type:number = 0
  115. private fastForwardSecond: FastForwardSecondInterface[] = [
  116. { label: '5秒', value: '5' },
  117. { label: '10秒', value: '10' },
  118. { label: '15秒', value: '15' },
  119. { label: '20秒', value: '20' },
  120. { label: '30秒', value: '30' },
  121. { label: '60秒', value: '60' },
  122. { label: '90秒', value: '90' },
  123. ];
  124. public static THEME_COLOR_LIST: Array<ThemeColorItem> = [
  125. { name: '玫瑰粉', color: '#FF4081', isVip: false },
  126. { name: '经典蓝', color: '#0A59F7', isVip: false },
  127. { name: '活力黄', color: '#FFC107', isVip: true },
  128. { name: '枫叶红', color: '#F44336', isVip: true },
  129. { name: '幻影紫', color: '#9C27B0', isVip: true },
  130. { name: '翡翠绿', color: '#64BB5C', isVip: true },
  131. { name: '竹青蓝', color: '#00BCD4', isVip: true },
  132. { name: '深空灰', color: '#607D8B', isVip: true },
  133. { name: '橙霞橙', color: '#FF9800', isVip: true },
  134. { name: '湖水蓝', color: '#00BFFF', isVip: true },
  135. { name: '柠檬绿', color: '#C6FF00', isVip: true },
  136. { name: '樱花粉', color: '#FF69B4', isVip: true },
  137. { name: '暮夜蓝', color: '#283593', isVip: true },
  138. { name: '薄荷青', color: '#1DE9B6', isVip: true },
  139. { name: '银沙灰', color: '#B0BEC5', isVip: true },
  140. { name: '自定义', color: '#ffecec', isVip: true }
  141. ];
  142. static readonly iS_START_AUTO_PLAY: string = 'isStartAutoPlay';
  143. static readonly iS_MEMORY_LAST_PLAY: string = 'isMemoryLastPlay';
  144. @State showApiDialog: boolean = false
  145. @State tempApiUrl: string = ''
  146. @State lyricApiUrl: string = PreferencesUtil.getStringSync('LRC_API', '')
  147. @State isBgPlayOpen: boolean = true //是否启用后台播放
  148. @State isAutoRatate: boolean = true //是否启用自动横竖屏
  149. @State isMemoryPlay: boolean = true //是否启用记忆播放
  150. @State isMediacodec: boolean = false //是否启用硬件解码
  151. @State isMusicMemoryPlay: boolean = false //是否启用记忆播放
  152. @State isMusicBGCover: boolean = true //播放背景随封面
  153. @State sortType: number = 4 //默认排序方式
  154. @State isStartAutoPlay: boolean = false //启动后自动播放
  155. @State isMemoryLastPlay: boolean = false //是否启用应用退出记忆最后一首的播放进度
  156. @State isShowSimi: boolean = false //是否显示私密音频
  157. @State isShowFAV: boolean = true //是否显示我的收藏
  158. @State isShowHistory: boolean = true //是否显示最近播放
  159. @State isShowPlayPageBack: boolean = false //是否显示播放页返回键
  160. @State isShowPrecious: boolean = false //播控条显示上一首按钮
  161. @State isShowSingleLineLyric: boolean = false //是否显示单行歌词
  162. @State isLogUploadEnabled: boolean = false //日志上传开关
  163. @State isClearingLogs: boolean = false //是否正在清除日志
  164. @State isShowHeader: boolean = true
  165. @State isCustomizeBg: boolean = false //自定义背景界面
  166. @State isCustomizeBgSheet: boolean = false //自定义背景界面
  167. @State isShowTitleBar: boolean = true //是否显示分类导航条
  168. @State isShowAllBar: boolean = true //是否显示播放全部条
  169. @State longPressSpeed: number = 3 //长按默认倍数
  170. @State blurValue: number = 0 //背景模糊
  171. @State bgBrightness: number = 0 //背景亮度
  172. @State isGridMusic: boolean = true //是否网格布局
  173. @State isCircleBtn: boolean = false //是否圆形播放按钮
  174. @State twoFingerType: number = 3 //双指放大瘦小Grid或list的大小
  175. @State isScrollHide: boolean = false //是否滚动隐藏
  176. @State isSameTimePlay: boolean = false //是否和其他app同时播放
  177. @State isCoverRectangle: boolean = false
  178. @State isSavePlayMode: boolean = true
  179. @State volumeSmall: boolean = false
  180. @State isCoverTopBig: boolean = false//顶部大封面部分手机显示会和播放控制页重叠
  181. @State isSwipe: boolean = false //listItem的左滑开关
  182. @State isPlayListBgGrass: boolean = true//是否播放列表玻璃透明效果
  183. @State is_auto_hide_progress: boolean = false
  184. @State openSkipSongAnimate: boolean = true//切歌动画效果
  185. @State isPlayPageSwipeNext: boolean = true // 播放页上滑切歌
  186. @State isShowFileName: boolean = false//切歌动画效果
  187. @State isLongNameRoLL: boolean = true//长歌名滚动
  188. @State customizeBgPath: string | undefined = '';
  189. context = getContext(this);
  190. @State showCoverApiDialog: boolean = false
  191. @State tempCoverApiUrl: string = ''
  192. @State coverApiUrl: string = PreferencesUtil.getStringSync('COVER_API', '')
  193. @State apiDialogType: 'lyric' | 'cover' = 'lyric'
  194. @State themeMode: number = 0 // 0: 跟随系统, 1: 浅色, 2: 深色
  195. @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number =
  196. ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
  197. @StorageLink('isDarkMode') isDarkMode: boolean = false // 是否启用深色模式
  198. /** 当前断点类型(如大屏/小屏) */
  199. @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
  200. @State verName: string = ''
  201. @StorageProp('themeColor') themeColor: string =
  202. PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  203. @State showColorPicker: boolean = false
  204. @State customColor: string = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  205. @State isThemeSheet: boolean = false // 主题设置弹窗显示状态
  206. @State isEqualizerSheet: boolean = false // 均衡器设置弹窗显示状态
  207. @State isBackupSheet: boolean = false // 备份与恢复弹窗显示状态
  208. @State colorRows: Array<Array<ThemeColorItem>> = chunkArray(SettingPage.THEME_COLOR_LIST, 2);
  209. @State colorGroup: string = "group"
  210. @StorageProp('topRectHeight') topRectHeight: number = 0;
  211. apiDialogController: CustomDialogController = new CustomDialogController({
  212. builder: CustomContentDialog({
  213. primaryTitle: this.apiDialogType === 'lyric' ? '修改歌词API地址' : '修改封面API地址',
  214. contentBuilder: () => {
  215. this.buildApiDialogContent();
  216. },
  217. buttons: [
  218. {
  219. value: '取消',
  220. action: () => {
  221. this.apiDialogController.close();
  222. }
  223. },
  224. {
  225. value: '保存',
  226. action: () => {
  227. if (this.apiDialogType === 'lyric') {
  228. this.lyricApiUrl = this.tempApiUrl.trim()
  229. PreferencesUtil.put('LRC_API', this.lyricApiUrl)
  230. this.getUIContext().getPromptAction().showToast({
  231. message: '保存成功,当前LRC_API:' + this.lyricApiUrl,
  232. duration: 2000,
  233. showMode: promptAction.ToastShowMode.TOP_MOST,
  234. bottom: 85
  235. })
  236. } else {
  237. this.coverApiUrl = this.tempApiUrl.trim()
  238. PreferencesUtil.put('COVER_API', this.coverApiUrl)
  239. this.getUIContext().getPromptAction().showToast({
  240. message: '保存成功,当前COVER_API:' + this.coverApiUrl,
  241. duration: 2000,
  242. showMode: promptAction.ToastShowMode.TOP_MOST,
  243. bottom: 85
  244. })
  245. }
  246. this.apiDialogController.close();
  247. }
  248. }
  249. ]
  250. }),
  251. autoCancel: true,
  252. alignment: DialogAlignment.Center
  253. })
  254. @Builder
  255. buildApiDialogContent() {
  256. Column() {
  257. TextInput({
  258. text: this.tempApiUrl,
  259. placeholder: this.apiDialogType === 'lyric' ? '请输入歌词API地址' : '请输入封面API地址'
  260. })
  261. .onChange((val: string) => {
  262. this.tempApiUrl = val
  263. })
  264. .width('90%')
  265. .height(60)
  266. }
  267. .width('100%')
  268. }
  269. // 组件生命周期
  270. aboutToAppear() {
  271. this.defalut_home_type = PreferencesUtil.getNumberSync('defalut_home_type', 0)
  272. this.showFindLocation = PreferencesUtil.getBooleanSync('showFindLocation', true)
  273. this.showZMIndex = PreferencesUtil.getBooleanSync('showZMIndex', false)
  274. this.autoHideTitle = PreferencesUtil.getBooleanSync('autoHideTitle', true)
  275. this.isShowPrecious = PreferencesUtil.getBooleanSync('isShowPrecious', false)
  276. this.isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN, true)
  277. this.isAutoRatate = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_RATATE, true)
  278. this.isMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_PLAY, true)
  279. this.isMediacodec = PreferencesUtil.getBooleanSync(SettingPage.IS_MIDIACODEC_OPEN, false)
  280. this.isMusicMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_MEMORY_PLAY, false)
  281. this.isMusicBGCover = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_BG_COVER, true)
  282. this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4)
  283. this.isShowSimi = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SIMI, false)
  284. this.isShowFAV = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_FAV, true)
  285. this.isShowHistory = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HISTORY, true)
  286. this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false)
  287. this.customizeBgPath = PreferencesUtil.getStringSync(SettingPage.IS_CUSTOMIZE_BG_PATH, '')
  288. this.isGridMusic = PreferencesUtil.getBooleanSync(SettingPage.IS_GRID_MUSIC, false)
  289. this.isScrollHide = PreferencesUtil.getBooleanSync(SettingPage.IS_SCROLL_HIDE, false)
  290. this.isSameTimePlay = PreferencesUtil.getBooleanSync(SettingPage.IS_SAMETIME_PLAY, false)
  291. this.isSavePlayMode = PreferencesUtil.getBooleanSync(SettingPage.iS_SAVE_PLAY_MODE, true)
  292. this.blurValue = PreferencesUtil.getNumberSync(SettingPage.CUSTOMIZE_BG_BLUR, 0)
  293. this.bgBrightness = PreferencesUtil.getNumberSync(SettingPage.BG_BRIGHTNESS, 0)
  294. this.isStartAutoPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_START_AUTO_PLAY, false)
  295. this.isMemoryLastPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_LAST_PLAY, false)
  296. this.twoFingerType = PreferencesUtil.getNumberSync(SettingPage.TWO_FINGER_TYPE, 2)
  297. this.isCircleBtn = PreferencesUtil.getBooleanSync(SettingPage.IS_CIRCLE_BTN, true)
  298. this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, false)
  299. this.isShowAllBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_ALLBAR, true)
  300. this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, true)
  301. this.isShowSingleLineLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SLLYRIC, false)
  302. this.isCoverTopBig = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP_BIG, false)
  303. this.longPressSpeed = PreferencesUtil.getNumberSync(SettingPage.LONG_PRESS_SPEED, 3)
  304. this.isShowHeader = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HEADER, true)
  305. this.isCoverRectangle = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_RECTANGLE, true)
  306. this.isPlayListBgGrass = PreferencesUtil.getBooleanSync(SettingPage.IS_PLAYLIST_BG_GRASS, true)
  307. this.isSwipe = PreferencesUtil.getBooleanSync(SettingPage.IS_SWIPE, true)
  308. this.is_auto_hide_progress = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_HIDE_PROGRESS, false)
  309. this.openSkipSongAnimate = PreferencesUtil.getBooleanSync(SettingPage.OPEN_SKIPSONG_ANIMATE, true)
  310. this.isPlayPageSwipeNext = PreferencesUtil.getBooleanSync(SettingPage.IS_PLAYPAGE_SWIPE_NEXT, true)
  311. this.volumeSmall = PreferencesUtil.getBooleanSync('volumeSmall', false)
  312. this.autoParseMusicName = PreferencesUtil.getBooleanSync('autoParseMusicName', true)
  313. this.isShowFileName = PreferencesUtil.getBooleanSync('isShowFileName', false)
  314. this.isLongNameRoLL = PreferencesUtil.getBooleanSync('isLongNameRoLL', true)
  315. this.isShowBackFast = PreferencesUtil.getBooleanSync('isShowBackFast', false)
  316. this.fastForwardSeconds = PreferencesUtil.getStringSync('fastForwardSeconds', '10')
  317. this.preloadNextSong = PreferencesUtil.getBooleanSync('preload_next_song', true)
  318. this.bluetoothDisconnectPause = PreferencesUtil.getBooleanSync(SettingPage.BLUETOOTH_DISCONNECT_PAUSE, false)
  319. this.bluetoothLyricEnabled = PreferencesUtil.getBooleanSync(SettingPage.BLUETOOTH_LYRIC_ENABLED, false)
  320. this.bluetoothLyricMode = PreferencesUtil.getNumberSync(SettingPage.BLUETOOTH_LYRIC_MODE, 0)
  321. this.isCopyFileToDownLoad = PreferencesUtil.getBooleanSync(SettingPage.IS_COPYFILE_TO_DOWNLOAD, false)
  322. this.isNoJumpToHome = PreferencesUtil.getBooleanSync('isNoJumpToHome', true)
  323. this.webdavUploadDuplicateAction = PreferencesUtil.getStringSync(SettingPage.WEBDAV_UPLOAD_DUPLICATE_ACTION, 'skip')
  324. this.webdavUploadAutoClear = PreferencesUtil.getBooleanSync(SettingPage.WEBDAV_UPLOAD_AUTO_CLEAR, false)
  325. this.webdavUploadAllowMobile = PreferencesUtil.getBooleanSync(SettingPage.WEBDAV_UPLOAD_ALLOW_MOBILE, false)
  326. this.webdavUploadRetryCount = PreferencesUtil.getNumberSync(SettingPage.WEBDAV_UPLOAD_RETRY_COUNT, 3)
  327. this.isLogUploadEnabled = PreferencesUtil.getBooleanSync(SettingPage.LOG_UPLOAD_ENABLED, false)
  328. if (this.isLogUploadEnabled) {
  329. this.ensureMeituUploadHandler(true)
  330. } else {
  331. this.registerLogUploadDisabled()
  332. }
  333. // 只用 themeMode 控制主题
  334. this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0)
  335. this.applyThemeMode(this.themeMode)
  336. let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  337. AppStorage.setOrCreate('themeColor', themeColor);
  338. this.themeColor = themeColor;
  339. this.initIcon()
  340. }
  341. initIcon(){
  342. this.iconCurrentID = PreferencesUtil.getStringSync('iconCurrentID', 'default')
  343. const iconItem:Icon = {
  344. iconUrl: 'default',
  345. iconId: 'default',
  346. enabled: false
  347. }
  348. this.iconArray.push(iconItem)
  349. try {
  350. appInfoManager.queryDynamicIcons()
  351. .then((queryResult: appInfoManager.DynamicIconInfo[]) => {
  352. hilog.info(0, 'TAG', "Succeeded in getting queryResult= " + JSON.stringify(queryResult));
  353. const iconList = JSON.parse(JSON.stringify(queryResult)) as Array<Icon>;
  354. this.iconArray = this.iconArray.concat(iconList)
  355. }).catch((error: BusinessError) => {
  356. hilog.error(0, 'TAG', "queryDynamicIcons failed, code: " + error.code + ", exception message: " + error.message);
  357. });
  358. } catch (error) {
  359. hilog.error(0, 'TAG', "queryDynamicIcons exception code: " + error.code + ", exception message: " + error.message);
  360. }
  361. }
  362. // 监听颜色模式变化
  363. onColorModeChange(): void {
  364. this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
  365. AppStorage.setOrCreate('isDarkMode', this.isDarkMode);
  366. }
  367. // 组件生命周期
  368. aboutToDisappear() {
  369. // 无需处理apiDialogController
  370. }
  371. applyThemeMode(mode: number) {
  372. let colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
  373. if (mode === 1) {
  374. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
  375. } else if (mode === 2) {
  376. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK
  377. }
  378. AppStorage.setOrCreate('currentColorMode', colorMode)
  379. AppStorage.setOrCreate('isDarkMode', colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
  380. PreferencesUtil.putSync(SettingPage.THEME_MODE, mode)
  381. AppStorage.setOrCreate('themeMode', mode)
  382. // 只有强制浅色/深色时才主动设置
  383. const context = getContext(this) as common.UIAbilityContext
  384. context.getApplicationContext().setColorMode(colorMode)
  385. }
  386. private logNetDisk(level: 'info' | 'warn' | 'error', message: string) {
  387. const tag = 'NetDiskSetting';
  388. switch (level) {
  389. case 'info':
  390. void ServerLogUtil.info(tag, message);
  391. break;
  392. case 'warn':
  393. void ServerLogUtil.warn(tag, message);
  394. break;
  395. case 'error':
  396. void ServerLogUtil.error(tag, message);
  397. break;
  398. default:
  399. break;
  400. }
  401. }
  402. private handleClearWebDavCache() {
  403. if (this.isClearingCache) {
  404. return;
  405. }
  406. this.isClearingCache = true;
  407. const manager = RemoteDriveManager.getInstance();
  408. const account = manager?.currentAccount;
  409. const accountId = account?.id;
  410. // 清除所有类型的网盘缓存(WebDAV、SMB、FTP、百度、Navidrome、Jellyfin、Emby)
  411. this.logNetDisk('info', `开始清除所有网盘缓存`);
  412. const clearPromise = clearAllRemoteCaches();
  413. clearPromise.then(() => {
  414. ToastUtil.showToast('已清除网盘缓存');
  415. this.logNetDisk('info', `清除所有网盘缓存成功`);
  416. }).catch((error: Error) => {
  417. hilog.error(0, 'SettingPage', `清除网盘缓存失败: ${error.message}`);
  418. ToastUtil.showToast('清除失败,请稍后重试');
  419. this.logNetDisk('error', `清除网盘缓存失败, err=${error.message}`);
  420. }).finally(() => {
  421. this.isClearingCache = false;
  422. this.logNetDisk('info', `网盘缓存清理结束`);
  423. });
  424. }
  425. private handleClearLogFiles() {
  426. if (this.isClearingLogs) {
  427. return;
  428. }
  429. // 显示确认对话框
  430. AlertDialog.show({
  431. title: '确认清除',
  432. message: '确定要清除所有日志文件吗?此操作不可撤销。',
  433. autoCancel: true,
  434. alignment: DialogAlignment.Bottom,
  435. primaryButton: {
  436. value: '确定清除',
  437. action: () => {
  438. this.clearLogFiles();
  439. }
  440. },
  441. secondaryButton: {
  442. value: '取消',
  443. action: () => {
  444. // 取消操作
  445. }
  446. }
  447. });
  448. }
  449. private deleteDirectoryRecursively(dirPath: string): void {
  450. try {
  451. if (!FileUtil.accessSync(dirPath)) {
  452. return;
  453. }
  454. if (FileUtil.isDirectory(dirPath)) {
  455. const files = FileUtil.listFileSync(dirPath);
  456. files.forEach((file: string) => {
  457. const filePath = `${dirPath}${FileUtil.separator}${file}`;
  458. this.deleteDirectoryRecursively(filePath);
  459. });
  460. FileUtil.rmdirSync(dirPath);
  461. } else {
  462. FileUtil.unlinkSync(dirPath);
  463. }
  464. } catch (error) {
  465. hilog.warn(0, 'SettingPage', `删除目录失败: ${dirPath}, 错误: ${JSON.stringify(error)}`);
  466. }
  467. }
  468. private async clearLogFiles() {
  469. this.isClearingLogs = true;
  470. try {
  471. let clearedCount = 0;
  472. // 清除错误日志
  473. const errorLogPath = FileUtil.getFilesDirPath('ErrorLog', 'errorLog.txt');
  474. if (FileUtil.accessSync(errorLogPath)) {
  475. FileUtil.unlinkSync(errorLogPath);
  476. clearedCount++;
  477. }
  478. // 清除Navidrome日志
  479. const navidromeLogDir = FileUtil.getFilesDirPath('NavidromeLog');
  480. if (FileUtil.accessSync(navidromeLogDir)) {
  481. try {
  482. const files = FileUtil.listFileSync(navidromeLogDir);
  483. files.forEach((file: string) => {
  484. const filePath = `${navidromeLogDir}${FileUtil.separator}${file}`;
  485. if (FileUtil.accessSync(filePath) && !FileUtil.isDirectory(filePath)) {
  486. FileUtil.unlinkSync(filePath);
  487. clearedCount++;
  488. }
  489. });
  490. } catch (error) {
  491. hilog.warn(0, 'SettingPage', `清除Navidrome日志目录时出错: ${JSON.stringify(error)}`);
  492. }
  493. }
  494. // 清除日志上传缓存
  495. const logUploadDir = FileUtil.getCacheDirPath('LogUpload');
  496. if (FileUtil.accessSync(logUploadDir)) {
  497. try {
  498. // 递归删除目录及其内容
  499. this.deleteDirectoryRecursively(logUploadDir);
  500. clearedCount++;
  501. } catch (error) {
  502. hilog.warn(0, 'SettingPage', `清除日志上传缓存时出错: ${JSON.stringify(error)}`);
  503. }
  504. }
  505. // 清除其他可能的日志文件
  506. const logFilePatterns = [
  507. 'app.log',
  508. 'debug.log',
  509. 'info.log',
  510. 'warn.log',
  511. 'crash.log'
  512. ];
  513. logFilePatterns.forEach((fileName: string) => {
  514. try {
  515. const filesDir = AppUtil.getContext().filesDir;
  516. const logFilePath = `${filesDir}${FileUtil.separator}${fileName}`;
  517. if (FileUtil.accessSync(logFilePath)) {
  518. FileUtil.unlinkSync(logFilePath);
  519. clearedCount++;
  520. }
  521. // 检查cache目录
  522. const cacheLogPath = `${AppUtil.getContext().cacheDir}${FileUtil.separator}${fileName}`;
  523. if (FileUtil.accessSync(cacheLogPath)) {
  524. FileUtil.unlinkSync(cacheLogPath);
  525. clearedCount++;
  526. }
  527. } catch (error) {
  528. hilog.warn(0, 'SettingPage', `清除日志文件 ${fileName} 时出错: ${JSON.stringify(error)}`);
  529. }
  530. });
  531. if (clearedCount > 0) {
  532. ToastUtil.showToast(`已清除 ${clearedCount} 个日志文件`);
  533. hilog.info(0, 'SettingPage', `成功清除 ${clearedCount} 个日志文件`);
  534. } else {
  535. ToastUtil.showToast('未找到需要清除的日志文件');
  536. }
  537. } catch (error) {
  538. const errorMessage = error instanceof Error ? error.message : '未知错误';
  539. hilog.error(0, 'SettingPage', `清除日志文件失败: ${errorMessage}`);
  540. ToastUtil.showToast('清除失败,请稍后重试');
  541. } finally {
  542. this.isClearingLogs = false;
  543. }
  544. }
  545. @Builder
  546. pickerBuilder() {
  547. Column({ space: 20 }) {
  548. HSBColorPicker({
  549. color: this.customColor,
  550. radius: 8,
  551. onChange: (value: string) => {
  552. this.customColor = value
  553. }
  554. })
  555. .layoutWeight(1)
  556. .padding(15)
  557. Row({ space: 10 }) {
  558. Button('取消')
  559. .stateEffect(true)
  560. .backgroundColor(this.themeColor)
  561. .onClick(() => {
  562. this.showColorPicker = false
  563. })
  564. Button('确定')
  565. .stateEffect(true)
  566. .backgroundColor(this.themeColor)
  567. .onClick(() => {
  568. this.themeColor = this.customColor
  569. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, this.customColor)
  570. AppStorage.setOrCreate('themeColor', this.customColor)
  571. this.sendChangeEvent()
  572. this.showColorPicker = false
  573. })
  574. }
  575. }
  576. .padding(20)
  577. .width('80%')
  578. .height(300)
  579. }
  580. @Builder
  581. equalizerSheetBuilder() {
  582. Scroll() {
  583. Column() {
  584. EqualizerView()
  585. .margin({ top: 8 })
  586. }
  587. .padding({ left: 12, right: 12, bottom: 20 })
  588. }
  589. .width('100%')
  590. .height('100%')
  591. }
  592. @Builder
  593. backupSheetBuilder() {
  594. BackupManageView()
  595. .width('100%')
  596. .height('100%')
  597. }
  598. @Builder
  599. themeSheetBuilder() {
  600. Column() {
  601. // 颜色模式分组卡片
  602. Column() {
  603. Row() {
  604. Row() {
  605. Image($r('app.media.theme'))
  606. .width(20)
  607. .height(20)
  608. .fillColor(this.themeColor)
  609. Text('颜色模式')
  610. .fontSize(15)
  611. .margin({ left: 6 })
  612. .fontWeight(500)
  613. }
  614. .layoutWeight(1)
  615. Blank()
  616. Row() {
  617. ForEach(['自动', '日间', '夜间'], (item: string, idx: number) => {
  618. Column() {
  619. Radio({
  620. value: idx.toString(),
  621. group: this.colorGroup,
  622. })
  623. .checked(this.themeMode === idx)
  624. .radioStyle({
  625. checkedBackgroundColor: this.themeColor
  626. })
  627. .margin({ left: 3, right: 3 })
  628. .onClick(() => {
  629. this.themeMode = idx
  630. this.applyThemeMode(idx)
  631. this.sendChangeEvent()
  632. })
  633. Text(item)
  634. .fontSize(15)
  635. .fontColor($r('app.color.text_color'))
  636. .margin({ top: 6 })
  637. .onClick(() => {
  638. this.themeMode = idx
  639. this.applyThemeMode(idx)
  640. this.sendChangeEvent()
  641. })
  642. }
  643. .alignItems(HorizontalAlign.Center)
  644. .margin({ left: 12, right: 12 })
  645. })
  646. }
  647. .margin({ left: 12, right: 12 })
  648. }
  649. }
  650. .backgroundColor($r('app.color.settings_background_main'))
  651. .borderRadius(18)
  652. .border({ width: 1, color: '#F0F0F0' })
  653. .shadow({
  654. radius: 12,
  655. color: 0x11000000,
  656. offsetX: 0,
  657. offsetY: 2
  658. })
  659. .margin({
  660. left: 0,
  661. right: 0,
  662. bottom: 20
  663. })
  664. .padding({
  665. top: 18,
  666. bottom: 18,
  667. left: 20,
  668. right: 20
  669. })
  670. .width('90%')
  671. // 主题色分组卡片
  672. Column() {
  673. Row() {
  674. SymbolGlyph($r('sys.symbol.paintpalette'))
  675. .fontSize(20)
  676. .fontColor([this.themeColor])
  677. Text('主题色')
  678. .fontSize(15)
  679. .fontWeight(500)
  680. .margin({ left: 8 })
  681. .layoutWeight(1)
  682. }
  683. .margin({ left: 20, top: 12 })
  684. Row() {
  685. Column() {
  686. ForEach(this.colorRows, (row: Array<ThemeColorItem>, rowIdx: number) => {
  687. Row() {
  688. ForEach(row, (item: ThemeColorItem, colIdx: number) => {
  689. Button() {
  690. Row() {
  691. Blank()
  692. .width(22)
  693. .height(22)
  694. .backgroundColor(item.name === '自定义' && this.isCustomThemeColor() ? this.themeColor :
  695. item.color)
  696. .border({ width: 2, color: $r('app.color.text_color') })
  697. .borderRadius(11)
  698. Text(item.name)
  699. .fontSize(15)
  700. .fontColor($r('app.color.text_color'))
  701. .margin({ left: 10 })
  702. // Text(item.isVip?'VIP':"Free")
  703. // .fontSize(10)
  704. // .fontColor(item.isVip?'#FFD700':"#000000") // 金色
  705. // .backgroundColor('#FFF9E3')
  706. // .borderRadius(6)
  707. // .padding({ left: 4, right: 4, top: 1, bottom: 1 })
  708. // .margin({ left: 4 })
  709. }
  710. .alignItems(VerticalAlign.Center)
  711. .justifyContent(FlexAlign.Start)
  712. .layoutWeight(1)
  713. }
  714. .height(40)
  715. .layoutWeight(1)
  716. .backgroundColor(
  717. (item.name === '自定义' && this.isCustomThemeColor()) || this.themeColor === item.color
  718. ? this.themeColor
  719. : $r('app.color.settings_background_main')
  720. )
  721. .borderRadius(20)
  722. .onClick(() => {
  723. if (item.isVip) {
  724. if (!Utility.isNoble()) {
  725. this.showVipDialog();
  726. return;
  727. }
  728. }
  729. if (item.name === '自定义') {
  730. this.showColorPicker = true
  731. } else {
  732. this.themeColor = item.color
  733. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, item.color)
  734. AppStorage.setOrCreate('themeColor', item.color)
  735. this.sendChangeEvent()
  736. }
  737. })
  738. .margin({ right: colIdx === 0 ? '4%' : 20, bottom: 10, left: 20 })
  739. })
  740. }
  741. .justifyContent(FlexAlign.Start)
  742. })
  743. }
  744. .margin({ left: 12, right: 12, top: 12 })
  745. }
  746. }
  747. .width('90%')
  748. .backgroundColor($r('app.color.settings_background_main'))
  749. .borderRadius(18)
  750. .border({ width: 1, color: '#F0F0F0' })
  751. .shadow({
  752. radius: 12,
  753. color: 0x11000000,
  754. offsetX: 0,
  755. offsetY: 2
  756. })
  757. .margin({
  758. left: 0,
  759. right: 0,
  760. bottom: 18
  761. })
  762. .padding({
  763. top: 18,
  764. bottom: 18,
  765. left: 0,
  766. right: 0
  767. })
  768. .bindPopup(this.showColorPicker, {
  769. builder: this.pickerBuilder(),
  770. placement: Placement.Top,
  771. mask: { color: '#33000000' },
  772. enableArrow: false, //是否显示箭头
  773. showInSubWindow: false,
  774. onStateChange: (e) => {
  775. if (!e.isVisible) {
  776. this.showColorPicker = false
  777. }
  778. }
  779. })
  780. // 主题色自定义弹窗
  781. }
  782. .padding({
  783. top: 8,
  784. bottom: 8,
  785. left: 15,
  786. right: 15
  787. })
  788. .width('100%')
  789. .backgroundColor(Color.Transparent)
  790. .borderRadius(24)
  791. }
  792. @Builder
  793. topTitleBar(){
  794. Column() {
  795. Row({ space: 15 }) {
  796. //左侧滑动按钮
  797. Button({ type: ButtonType.Circle, stateEffect: true }) {
  798. SymbolGlyph($r('sys.symbol.chevron_left'))
  799. .attributeModifier(new SymbolGlyphFancyModifier(25, '', ''))
  800. }
  801. .attributeModifier(new ButtonFancyModifier(40, 40))
  802. .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
  803. .animation({ duration: 300, curve: Curve.Ease })
  804. .onClick(() => {
  805. this.getUIContext()?.animateTo({ duration: 555 }, () => {
  806. this.mType =0
  807. })
  808. })
  809. .attributeModifier(new ShadowModifier())
  810. .zIndex(0)
  811. Text($r('app.string.setting'))
  812. .margin({left:3,right:10})
  813. .fontColor($r('app.color.text_color'))
  814. .fontSize(19)
  815. .maxLines(1)
  816. .textOverflow({ overflow: TextOverflow.MARQUEE })//超长滚动
  817. .layoutWeight(1)
  818. .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
  819. }
  820. }
  821. .padding({ top: this.topSafeHeight+10, left: 10, right: 10,bottom:12 })
  822. .width('100%')
  823. }
  824. build() {
  825. Column() {
  826. this.topTitleBar()
  827. // Column() {
  828. // Line().width('100%').height('100%')
  829. // }
  830. // .height(this.topRectHeight)
  831. // .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  832. // .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  833. //
  834. // // 自定义标题栏
  835. // Stack() {
  836. // // 居中标题
  837. // Text('通用设置')
  838. // .fontSize(20)
  839. // .fontColor(Color.White)
  840. // .align(Alignment.Center)
  841. // // 左侧返回按钮
  842. // Row() {
  843. // Image($r('app.media.left_back_white'))
  844. // .width(26)
  845. // .height(26)
  846. // .margin({ left: 12, right: 8 })
  847. // .onClick(() => {
  848. // this.getUIContext()?.animateTo({ duration: 555 }, () => {
  849. // // 动画闭包内控制Image组件的出现和消失
  850. // // this.isShowDrawer = !this.isShowDrawer
  851. // // this.offsetX = 0
  852. // this.mType =0
  853. // })
  854. // })
  855. // Blank().flexGrow(1)
  856. // Blank().width(32)
  857. // }
  858. // .height(48)
  859. // .width('100%')
  860. // .alignItems(VerticalAlign.Center)
  861. // }
  862. // .height(48)
  863. // .width('100%')
  864. // .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  865. Scroll() {
  866. Column() {
  867. // 主题设置分组
  868. Column() {
  869. Row() {
  870. Text('个性化')
  871. .margin({ left: 18, right: 20 })
  872. .fontSize(16)
  873. .fontColor(Color.Gray)
  874. .fontWeight(480)
  875. .layoutWeight(1)
  876. }
  877. .height(48)
  878. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  879. // 主题设置弹框入口
  880. Button({ type: ButtonType.Normal, stateEffect: true }) {
  881. Row() {
  882. SymbolGlyph($r('sys.symbol.sun_max'))
  883. .fontSize(20)
  884. .fontColor([this.themeColor])
  885. .alignSelf(ItemAlign.Center)
  886. .margin({ left: 15 })
  887. Text('主题设置')
  888. .margin({ left: 8 })
  889. .fontSize(15)
  890. .fontColor(Color.Gray)
  891. .fontWeight(480)
  892. .layoutWeight(1)
  893. Image($r('app.media.arrow_right'))
  894. .width(22)
  895. .height(22)
  896. .margin({ right: 18 })
  897. }
  898. }
  899. .backgroundColor(Color.Transparent)
  900. .height(55)
  901. .clickEffect({ level: ClickEffectLevel.HEAVY })
  902. .onClick(() => {
  903. this.showColorPicker = false;
  904. this.isThemeSheet = true;
  905. this.customColor = this.themeColor;
  906. })
  907. .bindSheet($$this.isThemeSheet, this.themeSheetBuilder(), {
  908. height: '95%',
  909. dragBar: true,
  910. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  911. showClose: true,
  912. blurStyle: BlurStyle.Thin,
  913. backgroundColor: Color.Transparent,
  914. title: { title: '主题设置' },
  915. shouldDismiss: (SheetDismiss: SheetDismiss) => {
  916. SheetDismiss.dismiss();
  917. this.showColorPicker = false;
  918. }
  919. })
  920. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  921. Button({ type: ButtonType.Normal, stateEffect: true }) {
  922. Row() {
  923. SymbolGlyph($r('sys.symbol.paintpalette'))
  924. .fontSize(20)
  925. .fontColor([this.themeColor])
  926. .alignSelf(ItemAlign.Center)
  927. .margin({ left: 15 })
  928. Text('自定义背景')
  929. .margin({ left: 8 })
  930. .fontSize(15)
  931. .fontColor(Color.Gray)
  932. .fontWeight(480)
  933. .layoutWeight(1)
  934. .bindSheet($$this.isCustomizeBgSheet, this.customizeBgSheet(), {
  935. height: '95%',
  936. dragBar: true,
  937. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  938. showClose: true,
  939. blurStyle: BlurStyle.Thin,
  940. backgroundColor: Color.Transparent,
  941. title: { title: '自定义背景' }
  942. })
  943. Blank()
  944. // 右侧箭头
  945. Image($r('app.media.arrow_right'))
  946. .width(22)
  947. .height(22)
  948. .margin({ left: 20, right: 20 })
  949. .align(Alignment.Center)
  950. }
  951. }
  952. .clickEffect({ level: ClickEffectLevel.HEAVY })
  953. .height(55)
  954. .onClick(() => {
  955. if (!Utility.isNoble()) {
  956. this.showVipDialog();
  957. return;
  958. }
  959. this.isCustomizeBgSheet = !this.isCustomizeBgSheet;
  960. })
  961. .backgroundColor(Color.Transparent)
  962. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  963. Button({ type: ButtonType.Normal, stateEffect: true }) {
  964. Row() {
  965. SymbolGlyph($r('sys.symbol.satellite_map'))
  966. .fontSize(20)
  967. .fontColor([this.themeColor])
  968. .alignSelf(ItemAlign.Center)
  969. .margin({ left: 15 })
  970. Text('自定义图标')
  971. .margin({ left: 8 })
  972. .fontSize(15)
  973. .fontColor(Color.Gray)
  974. .fontWeight(480)
  975. .layoutWeight(1)
  976. .bindSheet($$this.isCustomizeICONSheet, this.customizeICONSheet(), {
  977. height: this.isLandscape ? '95%' : '85%',
  978. dragBar: true,
  979. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  980. showClose: true,
  981. blurStyle: BlurStyle.Thin,
  982. backgroundColor: Color.Transparent,
  983. title: { title: '自定义图标' }
  984. })
  985. Blank()
  986. // 右侧箭头
  987. Image($r('app.media.arrow_right'))
  988. .width(22)
  989. .height(22)
  990. .margin({ left: 20, right: 20 })
  991. .align(Alignment.Center)
  992. }
  993. }
  994. .clickEffect({level:ClickEffectLevel.HEAVY})
  995. .height(55)
  996. .onClick(() => {
  997. if (!Utility.isNoble()) {
  998. this.showVipDialog();
  999. return;
  1000. }
  1001. this.isCustomizeICONSheet = !this.isCustomizeICONSheet;
  1002. })
  1003. .backgroundColor(Color.Transparent)
  1004. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1005. // 网格布局
  1006. Row() {
  1007. SymbolGlyph($r('sys.symbol.more'))
  1008. .fontSize(20)
  1009. .fontColor([this.themeColor])
  1010. .alignSelf(ItemAlign.Center)
  1011. .margin({ left: 15 })
  1012. Text('布局模式')
  1013. .margin({ left: 8 })
  1014. .fontSize(15)
  1015. .fontColor(Color.Gray)
  1016. .fontWeight(480)
  1017. .layoutWeight(1)
  1018. Select([
  1019. { value: CommonConstants.DEFAULT_LAYOUT[0] },
  1020. { value: CommonConstants.DEFAULT_LAYOUT[1] },
  1021. { value: CommonConstants.DEFAULT_LAYOUT[2] }])
  1022. .font({ size: 15, weight: FontWeight.Medium })
  1023. .fontColor(Color.Gray)
  1024. .margin({ right: 18 })
  1025. .selected(this.twoFingerType==4?0:
  1026. this.isGridMusic?2:1)
  1027. .value(CommonConstants.DEFAULT_LAYOUT[this.twoFingerType==4?0:
  1028. this.isGridMusic?2:1])
  1029. .onSelect(async (_index: number, text?: string | undefined) => {
  1030. if(_index == 0){
  1031. PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,4)
  1032. }else{
  1033. if(this.twoFingerType!=4){
  1034. PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,this.twoFingerType)
  1035. }else{
  1036. PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE,3)
  1037. }
  1038. if(_index == 1){
  1039. PreferencesUtil.put(SettingPage.IS_GRID_MUSIC,false)
  1040. }else{
  1041. PreferencesUtil.put(SettingPage.IS_GRID_MUSIC,true)
  1042. }
  1043. }
  1044. this.sendChangeEvent()
  1045. })
  1046. }
  1047. .height(55)
  1048. .clickEffect({level:ClickEffectLevel.HEAVY})
  1049. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1050. // 封面方形
  1051. Row() {
  1052. SymbolGlyph($r('sys.symbol.rectangle'))
  1053. .fontSize(20)
  1054. .fontColor([this.themeColor])
  1055. .alignSelf(ItemAlign.Center)
  1056. .margin({ left: 15 })
  1057. Text('封面方形')
  1058. .margin({ left: 8 })
  1059. .fontSize(15)
  1060. .fontColor(Color.Gray)
  1061. .fontWeight(480)
  1062. .layoutWeight(1)
  1063. Toggle({ type: ToggleType.Switch, isOn: this.isCoverRectangle })
  1064. .selectedColor(this.themeColor)
  1065. .switchPointColor(Color.White)
  1066. .margin({ right: 18 })
  1067. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1068. .onChange((checked: boolean) => {
  1069. this.isCoverRectangle = checked;
  1070. PreferencesUtil.put(SettingPage.IS_COVER_RECTANGLE, this.isCoverRectangle)
  1071. this.sendChangeEvent()
  1072. })
  1073. .width(50)
  1074. .height(30);
  1075. }
  1076. .height(55)
  1077. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1078. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1079. //导入视频复制一份到DownLoad目录
  1080. Row() {
  1081. SymbolGlyph($r('sys.symbol.save'))
  1082. .fontSize(20)
  1083. .fontColor([this.themeColor])
  1084. .alignSelf(ItemAlign.Center)
  1085. .margin({ left: 15 })
  1086. Text('导入音乐复制到DownLoad目录')
  1087. .margin({ left: 8 })
  1088. .fontSize(15)
  1089. .fontColor(Color.Gray)
  1090. .fontWeight(480)
  1091. .layoutWeight(1)
  1092. Toggle({ type: ToggleType.Switch, isOn: this.isCopyFileToDownLoad })
  1093. .selectedColor(this.themeColor)
  1094. .switchPointColor(Color.White)
  1095. .margin({ right: 18 })
  1096. .onChange((checked: boolean) => {
  1097. // if(!this.isCopyFileToDownLoad){
  1098. // ToastUtil.showToast("读取内嵌封面和歌词功能需要开启导入复制开关,不然没有权限读取。")
  1099. // }
  1100. this.isCopyFileToDownLoad = checked;
  1101. PreferencesUtil.put(SettingPage.IS_COPYFILE_TO_DOWNLOAD, this.isCopyFileToDownLoad)
  1102. this.sendChangeEvent()
  1103. })
  1104. .width(50)
  1105. .height(30);
  1106. }
  1107. .height(55)
  1108. .clickEffect({level:ClickEffectLevel.HEAVY})
  1109. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1110. //播放列表透明
  1111. Row() {
  1112. SymbolGlyph($r('sys.symbol.circle_lefthalf_inset_filled'))
  1113. .fontSize(20)
  1114. .fontColor([this.themeColor])
  1115. .alignSelf(ItemAlign.Center)
  1116. .margin({ left: 15 })
  1117. Text('播放列表背景透明')
  1118. .margin({ left: 8 })
  1119. .fontSize(15)
  1120. .fontColor(Color.Gray)
  1121. .fontWeight(480)
  1122. .layoutWeight(1)
  1123. Toggle({ type: ToggleType.Switch, isOn: this.isPlayListBgGrass })
  1124. .selectedColor(this.themeColor)
  1125. .switchPointColor(Color.White)
  1126. .margin({ right: 18 })
  1127. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1128. .onChange((checked: boolean) => {
  1129. this.isPlayListBgGrass = checked;
  1130. PreferencesUtil.put(SettingPage.IS_PLAYLIST_BG_GRASS, this.isPlayListBgGrass)
  1131. this.sendChangeEvent()
  1132. })
  1133. .width(50)
  1134. .height(30);
  1135. }
  1136. .height(55)
  1137. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1138. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1139. // 网格封面大
  1140. Row() {
  1141. SymbolGlyph($r('sys.symbol.picture'))
  1142. .fontSize(20)
  1143. .fontColor([this.themeColor])
  1144. .alignSelf(ItemAlign.Center)
  1145. .margin({ left: 15 })
  1146. Text('列表封面大小')
  1147. .margin({ left: 8 })
  1148. .fontSize(15)
  1149. .fontColor(Color.Gray)
  1150. .fontWeight(480)
  1151. .layoutWeight(1)
  1152. Select([
  1153. { value: CommonConstants.TWO_FINGER_TYPE[0] },
  1154. { value: CommonConstants.TWO_FINGER_TYPE[1] },
  1155. { value: CommonConstants.TWO_FINGER_TYPE[2] }])
  1156. .font({ size: 15, weight: FontWeight.Medium })
  1157. .fontColor(Color.Gray)
  1158. .margin({ right: 18 })
  1159. .selected(this.twoFingerType - 1)
  1160. .value(this.twoFingerType>3? CommonConstants.TWO_FINGER_TYPE[2]:
  1161. CommonConstants.TWO_FINGER_TYPE[this.twoFingerType-1])
  1162. .onSelect(async (_index: number, text?: string | undefined) => {
  1163. _index++;
  1164. this.twoFingerType = _index
  1165. PreferencesUtil.put(SettingPage.TWO_FINGER_TYPE, this.twoFingerType)
  1166. this.sendChangeEvent()
  1167. })
  1168. }
  1169. .height(55)
  1170. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1171. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1172. // 封面顶部
  1173. Row() {
  1174. SymbolGlyph($r('sys.symbol.shutter_photo'))
  1175. .fontSize(20)
  1176. .fontColor([this.themeColor])
  1177. .alignSelf(ItemAlign.Center)
  1178. .margin({ left: 15 })
  1179. Text('顶部大封面')
  1180. .margin({ left: 8 })
  1181. .fontSize(15)
  1182. .fontColor(Color.Gray)
  1183. .fontWeight(480)
  1184. .layoutWeight(1)
  1185. Toggle({ type: ToggleType.Switch, isOn: this.isCoverTopBig })
  1186. .selectedColor(this.themeColor)
  1187. .switchPointColor(Color.White)
  1188. .margin({ right: 18 })
  1189. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1190. .onChange((checked: boolean) => {
  1191. this.isCoverTopBig = checked;
  1192. if(this.isCoverTopBig){
  1193. ToastUtil.showToast('启动该开关部分设备封面太大导致和音乐控制重叠!')
  1194. }
  1195. PreferencesUtil.put(SettingPage.IS_COVER_TOP_BIG, this.isCoverTopBig)
  1196. this.sendChangeEvent()
  1197. })
  1198. .width(50)
  1199. .height(30);
  1200. }
  1201. .height(55)
  1202. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1203. .animation({
  1204. duration: 500,
  1205. curve: 'ease-in-out' // 可选动画曲线
  1206. })
  1207. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1208. // 切歌动画效果
  1209. Row() {
  1210. SymbolGlyph($r('sys.symbol.music'))
  1211. .fontSize(20)
  1212. .fontColor([this.themeColor])
  1213. .alignSelf(ItemAlign.Center)
  1214. .margin({ left: 15 })
  1215. Text('切歌动画效果')
  1216. .margin({ left: 8 })
  1217. .fontSize(15)
  1218. .fontColor(Color.Gray)
  1219. .fontWeight(480)
  1220. .layoutWeight(1)
  1221. Toggle({ type: ToggleType.Switch, isOn: this.openSkipSongAnimate })
  1222. .selectedColor(this.themeColor)
  1223. .switchPointColor(Color.White)
  1224. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1225. .margin({ right: 18 })
  1226. .onChange((checked: boolean) => {
  1227. this.openSkipSongAnimate = checked;
  1228. PreferencesUtil.put(SettingPage.OPEN_SKIPSONG_ANIMATE, this.openSkipSongAnimate)
  1229. this.sendChangeEvent()
  1230. })
  1231. .width(50)
  1232. .height(30);
  1233. }
  1234. .height(55)
  1235. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1236. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1237. // 播放页上滑切歌
  1238. Row() {
  1239. SymbolGlyph($r('sys.symbol.music_note_circle'))
  1240. .fontSize(20)
  1241. .fontColor([this.themeColor])
  1242. .alignSelf(ItemAlign.Center)
  1243. .margin({ left: 15 })
  1244. Text('播放页上滑切歌')
  1245. .margin({ left: 8 })
  1246. .fontSize(15)
  1247. .fontColor(Color.Gray)
  1248. .fontWeight(480)
  1249. .layoutWeight(1)
  1250. Toggle({ type: ToggleType.Switch, isOn: this.isPlayPageSwipeNext })
  1251. .selectedColor(this.themeColor)
  1252. .switchPointColor(Color.White)
  1253. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1254. .margin({ right: 18 })
  1255. .onChange((checked: boolean) => {
  1256. this.isPlayPageSwipeNext = checked;
  1257. PreferencesUtil.put(SettingPage.IS_PLAYPAGE_SWIPE_NEXT, this.isPlayPageSwipeNext)
  1258. this.sendChangeEvent()
  1259. })
  1260. .width(50)
  1261. .height(30);
  1262. }
  1263. .height(55)
  1264. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1265. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1266. // 圆形播放按钮
  1267. Row() {
  1268. SymbolGlyph($r('sys.symbol.circle'))
  1269. .fontSize(20)
  1270. .fontColor([this.themeColor])
  1271. .alignSelf(ItemAlign.Center)
  1272. .margin({ left: 15 })
  1273. Text('圆形播放按钮')
  1274. .margin({ left: 8 })
  1275. .fontSize(15)
  1276. .fontColor(Color.Gray)
  1277. .fontWeight(480)
  1278. .layoutWeight(1)
  1279. Toggle({ type: ToggleType.Switch, isOn: this.isCircleBtn })
  1280. .selectedColor(this.themeColor)
  1281. .switchPointColor(Color.White)
  1282. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1283. .margin({ right: 18 })
  1284. .onChange((checked: boolean) => {
  1285. this.isCircleBtn = checked;
  1286. PreferencesUtil.put(SettingPage.IS_CIRCLE_BTN, this.isCircleBtn)
  1287. this.sendChangeEvent()
  1288. })
  1289. .width(50)
  1290. .height(30);
  1291. }
  1292. .height(55)
  1293. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1294. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1295. }
  1296. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  1297. .animation({ duration: 500, curve: Curve.Ease, delay: 260 }))
  1298. .backgroundColor($r('app.color.settings_background_main'))
  1299. .borderRadius(20)
  1300. .margin({
  1301. left: 0,
  1302. right: 0,
  1303. top: 0,
  1304. bottom: 10
  1305. })
  1306. .padding(0)
  1307. // 网络工具
  1308. // Column() {
  1309. // Row() {
  1310. // Text('网络工具')
  1311. // .margin({ left: 18, right: 20 })
  1312. // .fontSize(16)
  1313. // .fontColor(Color.Gray)
  1314. // .fontWeight(480)
  1315. // .layoutWeight(1)
  1316. // }
  1317. // .height(48)
  1318. //
  1319. // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1320. // Button({ type: ButtonType.Normal, stateEffect: true }) {
  1321. // Row() {
  1322. // Image($r('app.media.cloudDisk'))
  1323. // .width(22)
  1324. // .height(22)
  1325. // .alignSelf(ItemAlign.Center)
  1326. // .margin({ left: 15 })
  1327. // Text('SMB 测试工具')
  1328. // .margin({ left: 8 })
  1329. // .fontSize(15)
  1330. // .fontColor(Color.Gray)
  1331. // .fontWeight(480)
  1332. // .layoutWeight(1)
  1333. // Image($r('app.media.arrow_right'))
  1334. // .width(22)
  1335. // .height(22)
  1336. // .margin({ right: 18 })
  1337. // }
  1338. // }
  1339. // .height(55)
  1340. // .backgroundColor(Color.Transparent)
  1341. // .clickEffect({ level: ClickEffectLevel.HEAVY })
  1342. // .onClick(() => {
  1343. // router.pushUrl({
  1344. // url: 'pages/SmbTestPage'
  1345. // });
  1346. // })
  1347. //
  1348. // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1349. // }
  1350. // .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  1351. // .animation({ duration: 500, curve: Curve.Ease, delay: 260 }))
  1352. // .backgroundColor($r('app.color.settings_background_main'))
  1353. // .borderRadius(20)
  1354. // .margin({
  1355. // left: 0,
  1356. // right: 0,
  1357. // top: 0,
  1358. // bottom: 10
  1359. // })
  1360. // .padding(0)
  1361. // 音频设置分组
  1362. Column() {
  1363. Row() {
  1364. Text('音频设置')
  1365. .margin({ left: 18, right: 20 })
  1366. .fontSize(16)
  1367. .fontColor(Color.Gray)
  1368. .fontWeight(480)
  1369. .layoutWeight(1)
  1370. }
  1371. .height(48)
  1372. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1373. // 启动时播放
  1374. Row() {
  1375. SymbolGlyph($r('sys.symbol.play_circle'))
  1376. .fontSize(20)
  1377. .fontColor([this.themeColor])
  1378. .alignSelf(ItemAlign.Center)
  1379. .margin({ left: 15 })
  1380. Text('启动时播放')
  1381. .margin({ left: 8 })
  1382. .fontSize(15)
  1383. .fontColor(Color.Gray)
  1384. .fontWeight(480)
  1385. .layoutWeight(1)
  1386. Toggle({ type: ToggleType.Switch, isOn: this.isStartAutoPlay })
  1387. .selectedColor(this.themeColor)
  1388. .switchPointColor(Color.White)
  1389. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1390. .margin({ right: 18 })
  1391. .onChange((checked: boolean) => {
  1392. this.isStartAutoPlay = checked;
  1393. PreferencesUtil.put(SettingPage.iS_START_AUTO_PLAY, this.isStartAutoPlay)
  1394. })
  1395. .width(50)
  1396. .height(30);
  1397. }
  1398. .height(55)
  1399. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1400. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1401. // 列表是否可左滑
  1402. Row() {
  1403. SymbolGlyph($r('sys.symbol.indentation_left'))
  1404. .fontSize(20)
  1405. .fontColor([this.themeColor])
  1406. .alignSelf(ItemAlign.Center)
  1407. .margin({ left: 15 })
  1408. Text('列表是否可左滑')
  1409. .margin({ left: 8 })
  1410. .fontSize(15)
  1411. .fontColor(Color.Gray)
  1412. .fontWeight(480)
  1413. .layoutWeight(1)
  1414. Toggle({ type: ToggleType.Switch, isOn: this.isSwipe })
  1415. .selectedColor(this.themeColor)
  1416. .switchPointColor(Color.White)
  1417. .margin({ right: 18 })
  1418. .onChange((checked: boolean) => {
  1419. this.isSwipe = checked;
  1420. PreferencesUtil.put(SettingPage.IS_SWIPE, this.isSwipe)
  1421. this.sendChangeEvent()
  1422. })
  1423. .width(50)
  1424. .height(30);
  1425. }
  1426. .height(55)
  1427. .clickEffect({level:ClickEffectLevel.HEAVY})
  1428. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1429. // 记住播放进度
  1430. Row() {
  1431. SymbolGlyph($r('sys.symbol.rectangle_split_3x1'))
  1432. .fontSize(20)
  1433. .fontColor([this.themeColor])
  1434. .alignSelf(ItemAlign.Center)
  1435. .margin({ left: 15 })
  1436. Text('记住最后一首进度')
  1437. .margin({ left: 8 })
  1438. .fontSize(15)
  1439. .fontColor(Color.Gray)
  1440. .fontWeight(480)
  1441. .layoutWeight(1)
  1442. Toggle({ type: ToggleType.Switch, isOn: this.isMemoryLastPlay })
  1443. .selectedColor(this.themeColor)
  1444. .switchPointColor(Color.White)
  1445. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1446. .margin({ right: 18 })
  1447. .onChange((checked: boolean) => {
  1448. this.isMemoryLastPlay = checked;
  1449. PreferencesUtil.put(SettingPage.iS_MEMORY_LAST_PLAY, this.isMemoryLastPlay)
  1450. this.sendChangeEvent()
  1451. })
  1452. .width(50)
  1453. .height(30);
  1454. }
  1455. .height(55)
  1456. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1457. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1458. // 记忆播放
  1459. Row() {
  1460. SymbolGlyph($r('sys.symbol.route_plan'))
  1461. .fontSize(20)
  1462. .fontColor([this.themeColor])
  1463. .alignSelf(ItemAlign.Center)
  1464. .margin({ left: 15 })
  1465. Text('记忆播放')
  1466. .margin({ left: 8 })
  1467. .fontSize(15)
  1468. .fontColor(Color.Gray)
  1469. .fontWeight(480)
  1470. .layoutWeight(1)
  1471. Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay })
  1472. .selectedColor(this.themeColor)
  1473. .switchPointColor(Color.White)
  1474. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1475. .margin({ right: 18 })
  1476. .onChange((checked: boolean) => {
  1477. this.isMusicMemoryPlay = checked;
  1478. PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay)
  1479. this.sendChangeEvent()
  1480. })
  1481. .width(50)
  1482. .height(30);
  1483. }
  1484. .height(55)
  1485. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1486. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1487. //显示快进快退
  1488. Row() {
  1489. SymbolGlyph($r('sys.symbol.hand_point_up_tap'))
  1490. .fontSize(20)
  1491. .fontColor([this.themeColor])
  1492. .alignSelf(ItemAlign.Center)
  1493. .margin({ left: 15 })
  1494. Text('显示快进快退')
  1495. .margin({ left: 8 })
  1496. .fontSize(15)
  1497. .fontColor(Color.Gray)
  1498. .fontWeight(480)
  1499. .layoutWeight(1)
  1500. Toggle({ type: ToggleType.Switch, isOn: this.isShowBackFast })
  1501. .selectedColor(this.themeColor)
  1502. .switchPointColor(Color.White)
  1503. .margin({ right: 18 })
  1504. .onChange((checked: boolean) => {
  1505. this.isShowBackFast = checked;
  1506. PreferencesUtil.put('isShowBackFast', this.isShowBackFast)
  1507. this.sendChangeEvent()
  1508. })
  1509. .width(50)
  1510. .height(30);
  1511. }
  1512. .height(55)
  1513. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1514. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1515. .opacity(this.isShowBackFast ? 1 : 0)
  1516. .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None)
  1517. .animation({
  1518. duration: 500,
  1519. curve: 'ease-in-out' // 可选动画曲线
  1520. })
  1521. // 快进快退时长
  1522. Row() {
  1523. SymbolGlyph($r('sys.symbol.hand_tap_wave_2'))
  1524. .fontSize(20)
  1525. .fontColor([this.themeColor])
  1526. .alignSelf(ItemAlign.Center)
  1527. .margin({ left: 15 })
  1528. Text('快进快退时长')
  1529. .margin({ left: 8 })
  1530. .fontSize(15)
  1531. .fontColor(Color.Gray)
  1532. .fontWeight(480)
  1533. .layoutWeight(1)
  1534. SelectItem({
  1535. list: this.fastForwardSecond.map(opt => opt.label),
  1536. selected: this.fastForwardSecond.findIndex(opt => opt.value === this.fastForwardSeconds),
  1537. onChange: (index: number) => {
  1538. this.fastForwardSeconds = this.fastForwardSecond[index].value;
  1539. PreferencesUtil.put('fastForwardSeconds', this.fastForwardSeconds)
  1540. this.sendChangeEvent()
  1541. }
  1542. })
  1543. }
  1544. .height(55)
  1545. .opacity(this.isShowBackFast ? 1 : 0)
  1546. .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None)
  1547. .animation({
  1548. duration: 500,
  1549. curve: 'ease-in-out' // 可选动画曲线
  1550. })
  1551. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1552. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1553. // 提前缓存下一首
  1554. Row() {
  1555. SymbolGlyph($r('sys.symbol.arrow_down_circle'))
  1556. .fontSize(20)
  1557. .fontColor([this.themeColor])
  1558. .alignSelf(ItemAlign.Center)
  1559. .margin({ left: 15 })
  1560. Text('提前缓存下一首')
  1561. .margin({ left: 8 })
  1562. .fontSize(15)
  1563. .fontColor(Color.Gray)
  1564. .fontWeight(480)
  1565. .layoutWeight(1)
  1566. Toggle({ type: ToggleType.Switch, isOn: this.preloadNextSong })
  1567. .selectedColor(this.themeColor)
  1568. .switchPointColor(Color.White)
  1569. .margin({ right: 18 })
  1570. .onChange((checked: boolean) => {
  1571. this.preloadNextSong = checked;
  1572. PreferencesUtil.put('preload_next_song', this.preloadNextSong)
  1573. this.sendChangeEvent()
  1574. ToastUtil.showToast(checked ? '已开启提前缓存下一首' : '已关闭提前缓存下一首')
  1575. })
  1576. .width(50)
  1577. .height(30);
  1578. }
  1579. .height(55)
  1580. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1581. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1582. // 蓝牙设备断开暂停
  1583. Row() {
  1584. SymbolGlyph($r('sys.symbol.bluetooth'))
  1585. .fontSize(20)
  1586. .fontColor([this.themeColor])
  1587. .alignSelf(ItemAlign.Center)
  1588. .margin({ left: 15 })
  1589. Text('蓝牙设备断开暂停播放')
  1590. .margin({ left: 8 })
  1591. .fontSize(15)
  1592. .fontColor(Color.Gray)
  1593. .fontWeight(480)
  1594. .layoutWeight(1)
  1595. Toggle({ type: ToggleType.Switch, isOn: this.bluetoothDisconnectPause })
  1596. .selectedColor(this.themeColor)
  1597. .switchPointColor(Color.White)
  1598. .margin({ right: 18 })
  1599. .onChange((checked: boolean) => {
  1600. this.bluetoothDisconnectPause = checked;
  1601. PreferencesUtil.put(SettingPage.BLUETOOTH_DISCONNECT_PAUSE, this.bluetoothDisconnectPause)
  1602. this.sendChangeEvent()
  1603. ToastUtil.showToast(checked ? '已开启蓝牙断开暂停' : '已关闭蓝牙断开暂停')
  1604. })
  1605. .width(50)
  1606. .height(30);
  1607. }
  1608. .height(55)
  1609. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1610. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1611. // 蓝牙歌词显示
  1612. Row() {
  1613. SymbolGlyph($r('sys.symbol.bluetooth'))
  1614. .fontSize(20)
  1615. .fontColor([this.themeColor])
  1616. .alignSelf(ItemAlign.Center)
  1617. .margin({ left: 15 })
  1618. Column({ space: 4 }) {
  1619. Text('蓝牙歌词显示')
  1620. .fontSize(15)
  1621. .fontColor(Color.Gray)
  1622. .fontWeight(480)
  1623. Text('连接蓝牙时在车机显示歌词')
  1624. .fontSize(12)
  1625. .fontColor(Color.Gray)
  1626. }
  1627. .layoutWeight(1)
  1628. .alignItems(HorizontalAlign.Start)
  1629. .margin({ left: 8 })
  1630. Toggle({ type: ToggleType.Switch, isOn: this.bluetoothLyricEnabled })
  1631. .selectedColor(this.themeColor)
  1632. .switchPointColor(Color.White)
  1633. .margin({ right: 18 })
  1634. .onChange((checked: boolean) => {
  1635. this.bluetoothLyricEnabled = checked;
  1636. PreferencesUtil.put(SettingPage.BLUETOOTH_LYRIC_ENABLED, this.bluetoothLyricEnabled)
  1637. this.sendChangeEvent()
  1638. ToastUtil.showToast(checked ? '已开启蓝牙歌词' : '已关闭蓝牙歌词')
  1639. })
  1640. .width(50)
  1641. .height(30);
  1642. }
  1643. .height(70)
  1644. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1645. // 蓝牙歌词显示模式(仅在开启时显示)
  1646. if (this.bluetoothLyricEnabled) {
  1647. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1648. Row() {
  1649. SymbolGlyph($r('sys.symbol.text_alignleft'))
  1650. .fontSize(20)
  1651. .fontColor([this.themeColor])
  1652. .alignSelf(ItemAlign.Center)
  1653. .margin({ left: 15 })
  1654. Text('歌词显示位置')
  1655. .margin({ left: 8 })
  1656. .fontSize(15)
  1657. .fontColor(Color.Gray)
  1658. .fontWeight(480)
  1659. .layoutWeight(1)
  1660. Select([
  1661. { value: '歌手位置(推荐)' },
  1662. { value: '歌名位置(兼容)' }])
  1663. .font({ size: 14, weight: FontWeight.Medium })
  1664. .fontColor(Color.Gray)
  1665. .margin({ right: 18 })
  1666. .selected(this.bluetoothLyricMode)
  1667. .value(this.bluetoothLyricMode === 0 ? '歌手位置(推荐)' : '歌名位置(兼容)')
  1668. .onSelect((_index: number, text?: string | undefined) => {
  1669. this.bluetoothLyricMode = _index
  1670. PreferencesUtil.put(SettingPage.BLUETOOTH_LYRIC_MODE, this.bluetoothLyricMode)
  1671. this.sendChangeEvent()
  1672. })
  1673. }
  1674. .height(55)
  1675. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1676. .animation({
  1677. duration: 300,
  1678. curve: 'ease-in-out'
  1679. })
  1680. }
  1681. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1682. // 均衡器设置入口
  1683. Button({ type: ButtonType.Normal, stateEffect: true }) {
  1684. Row() {
  1685. SymbolGlyph($r('sys.symbol.slider_vertical_3'))
  1686. .fontSize(20)
  1687. .fontColor([this.themeColor])
  1688. .alignSelf(ItemAlign.Center)
  1689. .margin({ left: 15 })
  1690. Text('均衡器')
  1691. .margin({ left: 8 })
  1692. .fontSize(15)
  1693. .fontColor(Color.Gray)
  1694. .fontWeight(480)
  1695. .layoutWeight(1)
  1696. Image($r('app.media.arrow_right'))
  1697. .width(22)
  1698. .height(22)
  1699. .margin({ right: 18 })
  1700. }
  1701. }
  1702. .backgroundColor(Color.Transparent)
  1703. .height(55)
  1704. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1705. .onClick(() => {
  1706. this.isEqualizerSheet = true;
  1707. })
  1708. .bindSheet($$this.isEqualizerSheet, this.equalizerSheetBuilder(), {
  1709. height: '70%',
  1710. dragBar: true,
  1711. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  1712. showClose: true,
  1713. blurStyle: BlurStyle.Thin,
  1714. backgroundColor: Color.Transparent,
  1715. title: { title: '均衡器设置' }
  1716. })
  1717. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1718. // 长按默认倍数
  1719. Row() {
  1720. SymbolGlyph($r('sys.symbol.timer'))
  1721. .fontSize(20)
  1722. .fontColor([this.themeColor])
  1723. .alignSelf(ItemAlign.Center)
  1724. .margin({ left: 15 })
  1725. Text('长按默认倍数')
  1726. .margin({ left: 8 })
  1727. .fontSize(15)
  1728. .fontColor(Color.Gray)
  1729. .fontWeight(480)
  1730. .layoutWeight(1)
  1731. Select([//倍速
  1732. { value: '0.25x' },
  1733. { value: '0.5x' },
  1734. { value: '0.75x' },
  1735. { value: '1x' },
  1736. { value: '1.25x' },
  1737. { value: '1.5x' },
  1738. { value: '1.75x' },
  1739. { value: '2x' },
  1740. { value: '2.5x' },
  1741. { value: '3x' }])
  1742. .font({ size: 15, weight: FontWeight.Medium })
  1743. .fontColor(Color.Gray)
  1744. .margin({right:18})
  1745. .selected(CommonConstants.video_speed_list.indexOf(this.longPressSpeed))
  1746. .value(Utility.optimizedFormat(this.longPressSpeed))
  1747. .onSelect(async (_index: number, text?: string | undefined) => {
  1748. let speed = parseFloat(text?.replace('x', '') || '1');
  1749. if (!CommonConstants.video_speed_list.includes(speed)) {
  1750. speed = 1;
  1751. }
  1752. this.longPressSpeed = speed
  1753. PreferencesUtil.put(SettingPage.LONG_PRESS_SPEED, this.longPressSpeed)
  1754. this.sendChangeEvent()
  1755. })
  1756. }
  1757. .height(55)
  1758. .clickEffect({level:ClickEffectLevel.HEAVY})
  1759. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1760. // 默认排序模式
  1761. Row() {
  1762. SymbolGlyph($r('sys.symbol.text_and_arrow_down'))
  1763. .fontSize(20)
  1764. .fontColor([this.themeColor])
  1765. .alignSelf(ItemAlign.Center)
  1766. .margin({ left: 15 })
  1767. Text('默认排序模式')
  1768. .margin({ left: 8 })
  1769. .fontSize(15)
  1770. .fontColor(Color.Gray)
  1771. .fontWeight(480)
  1772. .layoutWeight(1)
  1773. Select([
  1774. { value: CommonConstants.SORT_ARRAY[0] },
  1775. { value: CommonConstants.SORT_ARRAY[1] },
  1776. { value: CommonConstants.SORT_ARRAY[2] },
  1777. { value: CommonConstants.SORT_ARRAY[3] },
  1778. { value: CommonConstants.SORT_ARRAY[4] },
  1779. { value: CommonConstants.SORT_ARRAY[5] },
  1780. { value: CommonConstants.SORT_ARRAY[6] },
  1781. { value: CommonConstants.SORT_ARRAY[7] }])
  1782. .font({ size: 15, weight: FontWeight.Medium })
  1783. .fontColor(Color.Gray)
  1784. .margin({ right: 18 })
  1785. .selected(this.sortType)
  1786. .value(CommonConstants.SORT_ARRAY[this.sortType])
  1787. .onSelect(async (_index: number, text?: string | undefined) => {
  1788. this.sortType = _index
  1789. PreferencesUtil.put(SettingPage.SORT_TYPE, this.sortType)
  1790. this.sendChangeEvent()
  1791. })
  1792. }
  1793. .height(55)
  1794. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1795. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1796. // 首页默认
  1797. Row() {
  1798. SymbolGlyph($r('sys.symbol.home_button'))
  1799. .fontSize(20)
  1800. .fontColor([this.themeColor])
  1801. .alignSelf(ItemAlign.Center)
  1802. .margin({ left: 15 })
  1803. Text('首页默认')
  1804. .margin({ left: 8 })
  1805. .fontSize(15)
  1806. .fontColor(Color.Gray)
  1807. .fontWeight(480)
  1808. .layoutWeight(1)
  1809. Select([
  1810. { value: CommonConstants.DEFAULT_HOME_TYPE[0] },
  1811. { value: CommonConstants.DEFAULT_HOME_TYPE[1] },
  1812. { value: CommonConstants.DEFAULT_HOME_TYPE[2] },
  1813. { value: CommonConstants.DEFAULT_HOME_TYPE[3] },
  1814. { value: CommonConstants.DEFAULT_HOME_TYPE[4] }
  1815. ])
  1816. .font({ size: 15, weight: FontWeight.Medium })
  1817. .fontColor(Color.Gray)
  1818. .margin({ right: 18 })
  1819. .selected(this.defalut_home_type)
  1820. .value(CommonConstants.DEFAULT_HOME_TYPE[this.defalut_home_type])
  1821. .onSelect(async (_index: number, text?: string | undefined) => {
  1822. this.defalut_home_type = _index
  1823. PreferencesUtil.put('defalut_home_type', this.defalut_home_type)
  1824. this.sendChangeEvent()
  1825. })
  1826. }
  1827. .height(55)
  1828. .clickEffect({level:ClickEffectLevel.HEAVY})
  1829. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1830. // 列表显示音乐文件名
  1831. Row() {
  1832. SymbolGlyph($r('sys.symbol.text_clipboard'))
  1833. .fontSize(20)
  1834. .fontColor([this.themeColor])
  1835. .alignSelf(ItemAlign.Center)
  1836. .margin({ left: 15 })
  1837. Text('列表显示音乐文件名')
  1838. .margin({ left: 8 })
  1839. .fontSize(15)
  1840. .fontColor(Color.Gray)
  1841. .fontWeight(480)
  1842. .layoutWeight(1)
  1843. Toggle({ type: ToggleType.Switch, isOn: this.isShowFileName })
  1844. .selectedColor(this.themeColor)
  1845. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1846. .switchPointColor(Color.White)
  1847. .margin({ right: 18 })
  1848. .onChange((checked: boolean) => {
  1849. this.isShowFileName = checked;
  1850. PreferencesUtil.put('isShowFileName', this.isShowFileName)
  1851. this.sendChangeEvent()
  1852. })
  1853. .width(50)
  1854. .height(30);
  1855. }
  1856. .height(55)
  1857. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1858. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1859. // 网盘播放不跳转到首页
  1860. Row() {
  1861. SymbolGlyph($r('sys.symbol.close_sidebar'))
  1862. .fontSize(20)
  1863. .fontColor([this.themeColor])
  1864. .alignSelf(ItemAlign.Center)
  1865. .margin({ left: 15 })
  1866. Text('网盘播放不跳转到首页')
  1867. .margin({ left: 8 })
  1868. .fontSize(15)
  1869. .fontColor(Color.Gray)
  1870. .fontWeight(480)
  1871. .layoutWeight(1)
  1872. Toggle({ type: ToggleType.Switch, isOn: this.isNoJumpToHome })
  1873. .selectedColor(this.themeColor)
  1874. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1875. .switchPointColor(Color.White)
  1876. .margin({ right: 18 })
  1877. .onChange((checked: boolean) => {
  1878. this.isNoJumpToHome = checked;
  1879. PreferencesUtil.put('isNoJumpToHome', this.isNoJumpToHome)
  1880. })
  1881. .width(50)
  1882. .height(30);
  1883. }
  1884. .height(55)
  1885. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1886. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1887. // 备份与恢复
  1888. Button({ type: ButtonType.Normal, stateEffect: true }) {
  1889. Row() {
  1890. SymbolGlyph($r('sys.symbol.externaldrive'))
  1891. .fontSize(20)
  1892. .fontColor([this.themeColor])
  1893. .alignSelf(ItemAlign.Center)
  1894. .margin({ left: 15 })
  1895. Text('备份与恢复')
  1896. .margin({ left: 8 })
  1897. .fontSize(15)
  1898. .fontColor(Color.Gray)
  1899. .fontWeight(480)
  1900. .layoutWeight(1)
  1901. Image($r('app.media.arrow_right'))
  1902. .width(22)
  1903. .height(22)
  1904. .margin({ right: 18 })
  1905. }
  1906. }
  1907. .backgroundColor(Color.Transparent)
  1908. .height(55)
  1909. .width('100%')
  1910. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1911. .onClick(() => {
  1912. this.isBackupSheet = true;
  1913. })
  1914. .bindSheet($$this.isBackupSheet, this.backupSheetBuilder(), {
  1915. height: this.isLandscape ? '95%' : '85%',
  1916. dragBar: true,
  1917. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  1918. showClose: true,
  1919. blurStyle: BlurStyle.Thin,
  1920. backgroundColor: Color.Transparent,
  1921. title: { title: '备份与恢复' }
  1922. })
  1923. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1924. // 日志上传开关
  1925. Row() {
  1926. SymbolGlyph($r('sys.symbol.cloud'))
  1927. .fontSize(20)
  1928. .fontColor([this.themeColor])
  1929. .alignSelf(ItemAlign.Center)
  1930. .margin({ left: 15 })
  1931. Column({ space: 4 }) {
  1932. Text('开启日志上传')
  1933. .fontSize(15)
  1934. .fontColor(Color.Gray)
  1935. .fontWeight(480)
  1936. Text('开启后,在关于我们页连点Logo 8次将收集并上传日志')
  1937. .fontSize(12)
  1938. .fontColor(Color.Gray)
  1939. }
  1940. .layoutWeight(1)
  1941. .alignItems(HorizontalAlign.Start)
  1942. .margin({ left: 8 })
  1943. Toggle({ type: ToggleType.Switch, isOn: this.isLogUploadEnabled })
  1944. .selectedColor(this.themeColor)
  1945. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  1946. .switchPointColor(Color.White)
  1947. .margin({ right: 18 })
  1948. .onChange((checked: boolean) => {
  1949. this.isLogUploadEnabled = checked;
  1950. PreferencesUtil.put(SettingPage.LOG_UPLOAD_ENABLED, this.isLogUploadEnabled)
  1951. if (checked) {
  1952. const ok = this.ensureMeituUploadHandler(false);
  1953. if (ok) {
  1954. ToastUtil.showToast('已开启日志上传,关于我们页连点Logo 8次将上报')
  1955. }
  1956. } else {
  1957. this.registerLogUploadDisabled();
  1958. ToastUtil.showToast('已关闭日志上传')
  1959. }
  1960. })
  1961. .width(50)
  1962. .height(30);
  1963. }
  1964. .height(70)
  1965. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1966. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1967. // 清除日志文件按钮 - 只在开启日志上传时显示
  1968. if (this.isLogUploadEnabled) {
  1969. Row() {
  1970. SymbolGlyph($r('sys.symbol.trash_fill'))
  1971. .fontSize(20)
  1972. .fontColor([this.themeColor])
  1973. .alignSelf(ItemAlign.Center)
  1974. .margin({ left: 15 })
  1975. Column({ space: 4 }) {
  1976. Text('清除日志文件')
  1977. .fontSize(15)
  1978. .fontColor(Color.Gray)
  1979. .fontWeight(480)
  1980. Text('清除本地保存的所有日志文件')
  1981. .fontSize(12)
  1982. .fontColor(Color.Gray)
  1983. }.layoutWeight(1).margin({ left: 8 })
  1984. .alignItems(HorizontalAlign.Start)
  1985. Text(this.isClearingLogs ? '清除中…' : '立即清除')
  1986. .margin({ right: 18 })
  1987. .fontSize(13)
  1988. .fontColor(this.themeColor)
  1989. }
  1990. .height(55)
  1991. .clickEffect({ level: ClickEffectLevel.HEAVY })
  1992. .onClick(() => {
  1993. this.handleClearLogFiles();
  1994. })
  1995. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  1996. }
  1997. Row() {
  1998. SymbolGlyph($r('sys.symbol.trash'))
  1999. .fontSize(20)
  2000. .fontColor([this.themeColor])
  2001. .alignSelf(ItemAlign.Center)
  2002. .margin({ left: 15 })
  2003. Text('清除网盘缓存')
  2004. .margin({ left: 8 })
  2005. .fontSize(15)
  2006. .fontColor(Color.Gray)
  2007. .fontWeight(480)
  2008. .layoutWeight(1)
  2009. Text(this.isClearingCache ? '清理中…' : '立即清理')
  2010. .margin({ right: 18 })
  2011. .fontSize(13)
  2012. .fontColor(this.themeColor)
  2013. }
  2014. .height(55)
  2015. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2016. .onClick(() => {
  2017. this.handleClearWebDavCache();
  2018. })
  2019. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2020. // WebDAV上传默认重复文件处理方式
  2021. Row() {
  2022. SymbolGlyph($r('sys.symbol.doc'))
  2023. .fontSize(20)
  2024. .fontColor([this.themeColor])
  2025. .alignSelf(ItemAlign.Center)
  2026. .margin({ left: 15 })
  2027. Text('上传重复文件处理')
  2028. .margin({ left: 8 })
  2029. .fontSize(15)
  2030. .fontColor(Color.Gray)
  2031. .fontWeight(480)
  2032. .layoutWeight(1)
  2033. Select([
  2034. { value: '跳过' },
  2035. { value: '覆盖' },
  2036. { value: '重命名' }])
  2037. .font({ size: 15, weight: FontWeight.Medium })
  2038. .fontColor(Color.Gray)
  2039. .margin({ right: 18 })
  2040. .selected(this.webdavUploadDuplicateAction === 'skip' ? 0 :
  2041. this.webdavUploadDuplicateAction === 'overwrite' ? 1 : 2)
  2042. .value(this.webdavUploadDuplicateAction === 'skip' ? '跳过' :
  2043. this.webdavUploadDuplicateAction === 'overwrite' ? '覆盖' : '重命名')
  2044. .onSelect((_index: number, text?: string | undefined) => {
  2045. if (_index === 0) {
  2046. this.webdavUploadDuplicateAction = 'skip';
  2047. } else if (_index === 1) {
  2048. this.webdavUploadDuplicateAction = 'overwrite';
  2049. } else {
  2050. this.webdavUploadDuplicateAction = 'rename';
  2051. }
  2052. PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_DUPLICATE_ACTION, this.webdavUploadDuplicateAction)
  2053. })
  2054. }
  2055. .height(55)
  2056. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2057. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2058. // WebDAV上传完成后自动清理队列
  2059. Row() {
  2060. SymbolGlyph($r('sys.symbol.trash'))
  2061. .fontSize(20)
  2062. .fontColor([this.themeColor])
  2063. .alignSelf(ItemAlign.Center)
  2064. .margin({ left: 15 })
  2065. Text('上传完成自动清理队列')
  2066. .margin({ left: 8 })
  2067. .fontSize(15)
  2068. .fontColor(Color.Gray)
  2069. .fontWeight(480)
  2070. .layoutWeight(1)
  2071. Toggle({ type: ToggleType.Switch, isOn: this.webdavUploadAutoClear })
  2072. .selectedColor(this.themeColor)
  2073. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2074. .switchPointColor(Color.White)
  2075. .margin({ right: 18 })
  2076. .onChange((checked: boolean) => {
  2077. this.webdavUploadAutoClear = checked;
  2078. PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_AUTO_CLEAR, this.webdavUploadAutoClear)
  2079. })
  2080. .width(50)
  2081. .height(30);
  2082. }
  2083. .height(55)
  2084. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2085. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2086. // WebDAV是否允许移动网络上传
  2087. Row() {
  2088. SymbolGlyph($r('sys.symbol.wifi'))
  2089. .fontSize(20)
  2090. .fontColor([this.themeColor])
  2091. .alignSelf(ItemAlign.Center)
  2092. .margin({ left: 15 })
  2093. Text('允许移动网络上传')
  2094. .margin({ left: 8 })
  2095. .fontSize(15)
  2096. .fontColor(Color.Gray)
  2097. .fontWeight(480)
  2098. .layoutWeight(1)
  2099. Toggle({ type: ToggleType.Switch, isOn: this.webdavUploadAllowMobile })
  2100. .selectedColor(this.themeColor)
  2101. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2102. .switchPointColor(Color.White)
  2103. .margin({ right: 18 })
  2104. .onChange((checked: boolean) => {
  2105. this.webdavUploadAllowMobile = checked;
  2106. PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_ALLOW_MOBILE, this.webdavUploadAllowMobile)
  2107. })
  2108. .width(50)
  2109. .height(30);
  2110. }
  2111. .height(55)
  2112. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2113. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2114. // WebDAV上传失败自动重试次数
  2115. Row() {
  2116. SymbolGlyph($r('sys.symbol.arrow_clockwise'))
  2117. .fontSize(20)
  2118. .fontColor([this.themeColor])
  2119. .alignSelf(ItemAlign.Center)
  2120. .margin({ left: 15 })
  2121. Text('上传失败重试次数')
  2122. .margin({ left: 8 })
  2123. .fontSize(15)
  2124. .fontColor(Color.Gray)
  2125. .fontWeight(480)
  2126. .layoutWeight(1)
  2127. Select([
  2128. { value: '0次' },
  2129. { value: '1次' },
  2130. { value: '2次' },
  2131. { value: '3次' },
  2132. { value: '5次' }])
  2133. .font({ size: 15, weight: FontWeight.Medium })
  2134. .fontColor(Color.Gray)
  2135. .margin({ right: 18 })
  2136. .selected(this.webdavUploadRetryCount === 0 ? 0 :
  2137. this.webdavUploadRetryCount === 1 ? 1 :
  2138. this.webdavUploadRetryCount === 2 ? 2 :
  2139. this.webdavUploadRetryCount === 3 ? 3 : 4)
  2140. .value(this.webdavUploadRetryCount === 0 ? '0次' :
  2141. this.webdavUploadRetryCount === 1 ? '1次' :
  2142. this.webdavUploadRetryCount === 2 ? '2次' :
  2143. this.webdavUploadRetryCount === 3 ? '3次' : '5次')
  2144. .onSelect((_index: number, text?: string | undefined) => {
  2145. if (_index === 0) {
  2146. this.webdavUploadRetryCount = 0;
  2147. } else if (_index === 1) {
  2148. this.webdavUploadRetryCount = 1;
  2149. } else if (_index === 2) {
  2150. this.webdavUploadRetryCount = 2;
  2151. } else if (_index === 3) {
  2152. this.webdavUploadRetryCount = 3;
  2153. } else {
  2154. this.webdavUploadRetryCount = 5;
  2155. }
  2156. PreferencesUtil.put(SettingPage.WEBDAV_UPLOAD_RETRY_COUNT, this.webdavUploadRetryCount)
  2157. })
  2158. }
  2159. .height(55)
  2160. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2161. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2162. // 长歌名滚动
  2163. Row() {
  2164. SymbolGlyph($r('sys.symbol.close_sidebar'))
  2165. .fontSize(20)
  2166. .fontColor([this.themeColor])
  2167. .alignSelf(ItemAlign.Center)
  2168. .margin({ left: 15 })
  2169. Text('长歌名滚动')
  2170. .margin({ left: 8 })
  2171. .fontSize(15)
  2172. .fontColor(Color.Gray)
  2173. .fontWeight(480)
  2174. .layoutWeight(1)
  2175. Toggle({ type: ToggleType.Switch, isOn: this.isLongNameRoLL })
  2176. .selectedColor(this.themeColor)
  2177. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2178. .switchPointColor(Color.White)
  2179. .margin({ right: 18 })
  2180. .onChange((checked: boolean) => {
  2181. this.isLongNameRoLL = checked;
  2182. PreferencesUtil.put('isLongNameRoLL', this.isLongNameRoLL)
  2183. this.sendChangeEvent()
  2184. })
  2185. .width(50)
  2186. .height(30);
  2187. }
  2188. .height(55)
  2189. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2190. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2191. // 音量优化
  2192. Row() {
  2193. SymbolGlyph($r('sys.symbol.speaker'))
  2194. .fontSize(20)
  2195. .fontColor([this.themeColor])
  2196. .alignSelf(ItemAlign.Center)
  2197. .margin({ left: 15 })
  2198. Text('音量优化')
  2199. .margin({ left: 8 })
  2200. .fontSize(15)
  2201. .fontColor(Color.Gray)
  2202. .fontWeight(480)
  2203. .layoutWeight(1)
  2204. Toggle({ type: ToggleType.Switch, isOn: this.volumeSmall })
  2205. .selectedColor(this.themeColor)
  2206. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2207. .switchPointColor(Color.White)
  2208. .margin({ right: 18 })
  2209. .onChange((checked: boolean) => {
  2210. this.volumeSmall = checked;
  2211. if(this.volumeSmall){
  2212. ToastUtil.showToast('打开音量优化会比平时音量声音低些')
  2213. }
  2214. PreferencesUtil.put('volumeSmall', this.volumeSmall)
  2215. })
  2216. .width(50)
  2217. .height(30);
  2218. }
  2219. .height(55)
  2220. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2221. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2222. // 智能解析
  2223. Row() {
  2224. SymbolGlyph($r('sys.symbol.t_circle'))
  2225. .fontSize(20)
  2226. .fontColor([this.themeColor])
  2227. .alignSelf(ItemAlign.Center)
  2228. .margin({ left: 15 })
  2229. Text('智能文件名解析歌曲标签')
  2230. .margin({ left: 8 })
  2231. .fontSize(15)
  2232. .fontColor(Color.Gray)
  2233. .fontWeight(480)
  2234. .layoutWeight(1)
  2235. Toggle({ type: ToggleType.Switch, isOn: this.autoParseMusicName })
  2236. .selectedColor(this.themeColor)
  2237. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2238. .switchPointColor(Color.White)
  2239. .margin({ right: 18 })
  2240. .onChange((checked: boolean) => {
  2241. this.autoParseMusicName = checked;
  2242. PreferencesUtil.put('autoParseMusicName', this.autoParseMusicName)
  2243. })
  2244. .width(50)
  2245. .height(30);
  2246. }
  2247. .height(55)
  2248. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2249. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2250. // 保存播放模式
  2251. Row() {
  2252. SymbolGlyph($r('sys.symbol.clock'))
  2253. .fontSize(20)
  2254. .fontColor([this.themeColor])
  2255. .alignSelf(ItemAlign.Center)
  2256. .margin({ left: 15 })
  2257. Text('保存播放模式')
  2258. .margin({ left: 8 })
  2259. .fontSize(15)
  2260. .fontColor(Color.Gray)
  2261. .fontWeight(480)
  2262. .layoutWeight(1)
  2263. Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode })
  2264. .selectedColor(this.themeColor)
  2265. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2266. .switchPointColor(Color.White)
  2267. .margin({ right: 18 })
  2268. .onChange((checked: boolean) => {
  2269. this.isSavePlayMode = checked;
  2270. PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode)
  2271. })
  2272. .width(50)
  2273. .height(30);
  2274. }
  2275. .height(55)
  2276. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2277. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2278. Row() {
  2279. SymbolGlyph($r('sys.symbol.sun_max'))
  2280. .fontSize(20)
  2281. .fontColor([this.themeColor])
  2282. .alignSelf(ItemAlign.Center)
  2283. .margin({ left: 15 })
  2284. Text('与其他应用同时播放')
  2285. .margin({ left: 8 })
  2286. .fontSize(15)
  2287. .fontColor(Color.Gray)
  2288. .fontWeight(480)
  2289. .layoutWeight(1)
  2290. Toggle({ type: ToggleType.Switch, isOn: this.isSameTimePlay })
  2291. .selectedColor(this.themeColor)
  2292. .switchPointColor(Color.White)
  2293. .margin({ right: 18 })
  2294. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2295. .onChange((checked: boolean) => {
  2296. this.isSameTimePlay = checked;
  2297. PreferencesUtil.put(SettingPage.IS_SAMETIME_PLAY, this.isSameTimePlay)
  2298. this.sendChangeEvent()
  2299. })
  2300. .width(50)
  2301. .height(30);
  2302. }
  2303. .height(55).clickEffect({ level: ClickEffectLevel.HEAVY })
  2304. // .visibility(Visibility.None)
  2305. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2306. // 播放背景随音乐封面
  2307. Row() {
  2308. SymbolGlyph($r('sys.symbol.paperplane'))
  2309. .fontSize(20)
  2310. .fontColor([this.themeColor])
  2311. .alignSelf(ItemAlign.Center)
  2312. .margin({ left: 15 })
  2313. Text('播放背景随音乐封面')
  2314. .margin({ left: 8 })
  2315. .fontSize(15)
  2316. .fontColor(Color.Gray)
  2317. .fontWeight(480)
  2318. .layoutWeight(1)
  2319. Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover })
  2320. .selectedColor(this.themeColor)
  2321. .switchPointColor(Color.White)
  2322. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2323. .margin({ right: 18 })
  2324. .onChange((checked: boolean) => {
  2325. this.isMusicBGCover = checked;
  2326. PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover)
  2327. })
  2328. .width(50)
  2329. .height(30);
  2330. }
  2331. .height(55)
  2332. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2333. }
  2334. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  2335. .animation({ duration: 500, curve: Curve.Ease, delay: 400 }))
  2336. .backgroundColor($r('app.color.settings_background_main'))
  2337. .borderRadius(20)
  2338. .margin({
  2339. left: 0,
  2340. right: 0,
  2341. top: 10,
  2342. bottom: 10
  2343. })
  2344. .padding(0)
  2345. // API设置分组
  2346. this.apiBuilder()
  2347. //设置教程
  2348. this.jcBuilder()
  2349. //显示与隐藏设置
  2350. this.xsBuilder()
  2351. //空白
  2352. Column() {
  2353. Blank()
  2354. .height(88)
  2355. }.height(88)
  2356. }
  2357. .margin({
  2358. left: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  2359. right: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  2360. top: 20,
  2361. bottom: 20
  2362. })
  2363. .justifyContent(FlexAlign.Start)
  2364. }
  2365. .scrollBar(BarState.Auto)
  2366. .width('100%')
  2367. .margin({ bottom: 10 })
  2368. .backgroundColor($r('app.color.settings_background'))
  2369. }
  2370. .layoutWeight(1)
  2371. .height('100%')
  2372. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  2373. }
  2374. @Builder
  2375. xsBuilder() {
  2376. // 显示和隐藏分组
  2377. Column() {
  2378. Row() {
  2379. Text('显示隐藏')
  2380. .margin({ left: 18, right: 20 })
  2381. .fontSize(16)
  2382. .fontColor(Color.Gray)
  2383. .fontWeight(480)
  2384. .layoutWeight(1)
  2385. }
  2386. .onClick(() => {
  2387. ToastUtil.showToast(this.appIdentifier)
  2388. PreferencesUtil.putSync('isShowWX',true)
  2389. })
  2390. .height(48)
  2391. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2392. Row() {
  2393. SymbolGlyph($r('sys.symbol.text_clipboard'))
  2394. .fontSize(20)
  2395. .fontColor([this.themeColor])
  2396. .alignSelf(ItemAlign.Center)
  2397. .margin({ left: 15 })
  2398. Text('滚动隐藏标题栏')
  2399. .margin({ left: 8 })
  2400. .fontSize(15)
  2401. .fontColor(Color.Gray)
  2402. .fontWeight(480)
  2403. .layoutWeight(1)
  2404. Toggle({ type: ToggleType.Switch, isOn: this.autoHideTitle })
  2405. .selectedColor(this.themeColor)
  2406. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2407. .switchPointColor(Color.White)
  2408. .margin({ right: 18 })
  2409. .onChange((checked: boolean) => {
  2410. this.autoHideTitle = checked;
  2411. PreferencesUtil.put('autoHideTitle', this.autoHideTitle)
  2412. this.sendChangeEvent()
  2413. })
  2414. .width(50)
  2415. .height(30);
  2416. }
  2417. .height(55)
  2418. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2419. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2420. Row() {
  2421. SymbolGlyph($r('sys.symbol.label'))
  2422. .fontSize(20)
  2423. .fontColor([this.themeColor])
  2424. .alignSelf(ItemAlign.Center)
  2425. .margin({ left: 15 })
  2426. Text('显示右侧字母索引')
  2427. .margin({ left: 8 })
  2428. .fontSize(15)
  2429. .fontColor(Color.Gray)
  2430. .fontWeight(480)
  2431. .layoutWeight(1)
  2432. Toggle({ type: ToggleType.Switch, isOn: this.showZMIndex })
  2433. .selectedColor(this.themeColor)
  2434. .switchPointColor(Color.White)
  2435. .margin({ right: 18 })
  2436. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2437. .onChange((checked: boolean) => {
  2438. this.showZMIndex = checked;
  2439. PreferencesUtil.put('showZMIndex', this.showZMIndex)
  2440. if(this.showZMIndex){
  2441. ToastUtil.showToast('注意只在按名称排序中生效')
  2442. }
  2443. this.sendChangeEvent()
  2444. })
  2445. .width(50)
  2446. .height(30);
  2447. }
  2448. .height(55)
  2449. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2450. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2451. Row() {
  2452. SymbolGlyph($r('sys.symbol.local_fill'))
  2453. .fontSize(20)
  2454. .fontColor([this.themeColor])
  2455. .alignSelf(ItemAlign.Center)
  2456. .margin({ left: 15 })
  2457. Text('定位歌曲按钮')
  2458. .margin({ left: 8 })
  2459. .fontSize(15)
  2460. .fontColor(Color.Gray)
  2461. .fontWeight(480)
  2462. .layoutWeight(1)
  2463. Toggle({ type: ToggleType.Switch, isOn: this.showFindLocation })
  2464. .selectedColor(this.themeColor)
  2465. .switchPointColor(Color.White)
  2466. .margin({ right: 18 })
  2467. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2468. .onChange((checked: boolean) => {
  2469. this.showFindLocation = checked;
  2470. PreferencesUtil.put('showFindLocation', this.showFindLocation)
  2471. this.sendChangeEvent()
  2472. })
  2473. .width(50)
  2474. .height(30);
  2475. }
  2476. .height(55)
  2477. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2478. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2479. // 播放页单行歌词
  2480. Row() {
  2481. SymbolGlyph($r('sys.symbol.close_sidebar'))
  2482. .fontSize(20)
  2483. .fontColor([this.themeColor])
  2484. .alignSelf(ItemAlign.Center)
  2485. .margin({ left: 15 })
  2486. Text('播放页单行歌词')
  2487. .margin({ left: 8 })
  2488. .fontSize(15)
  2489. .fontColor(Color.Gray)
  2490. .fontWeight(480)
  2491. .layoutWeight(1)
  2492. Toggle({ type: ToggleType.Switch, isOn: this.isShowSingleLineLyric })
  2493. .selectedColor(this.themeColor)
  2494. .switchPointColor(Color.White)
  2495. .margin({ right: 18 })
  2496. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2497. .onChange((checked: boolean) => {
  2498. this.isShowSingleLineLyric = checked;
  2499. PreferencesUtil.put(SettingPage.IS_SHOW_SLLYRIC, this.isShowSingleLineLyric)
  2500. this.sendChangeEvent()
  2501. })
  2502. .width(50)
  2503. .height(30);
  2504. }
  2505. .height(55)
  2506. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2507. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2508. // 二级菜单新风格
  2509. // Row() {
  2510. // SymbolGlyph($r('sys.symbol.satellite_map'))
  2511. // .fontSize(20)
  2512. // .fontColor([this.themeColor])
  2513. // .alignSelf(ItemAlign.Center)
  2514. // .margin({ left: 15 })
  2515. // Text('二级菜单新风格')
  2516. // .margin({ left: 8 })
  2517. // .fontSize(15)
  2518. // .fontColor(Color.Gray)
  2519. // .fontWeight(480)
  2520. // .layoutWeight(1)
  2521. // Toggle({ type: ToggleType.Switch, isOn: this.isShowHeader })
  2522. // .selectedColor(this.themeColor)
  2523. // .switchPointColor(Color.White)
  2524. // .margin({ right: 18 })
  2525. // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2526. // .onChange((checked: boolean) => {
  2527. // this.isShowHeader = checked;
  2528. // PreferencesUtil.put(SettingPage.IS_SHOW_HEADER, this.isShowHeader)
  2529. // this.sendChangeEvent()
  2530. // })
  2531. // .width(50)
  2532. // .height(30);
  2533. // }
  2534. // .height(55)
  2535. // .clickEffect({ level: ClickEffectLevel.HEAVY })
  2536. //
  2537. // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2538. //播控条显示上一首按钮
  2539. Row() {
  2540. SymbolGlyph($r('sys.symbol.backward_end_fill'))
  2541. .fontSize(20)
  2542. .fontColor([this.themeColor])
  2543. .alignSelf(ItemAlign.Center)
  2544. .margin({ left: 15 })
  2545. Text('播控条上一首按钮')
  2546. .margin({ left: 8 })
  2547. .fontSize(15)
  2548. .fontColor(Color.Gray)
  2549. .fontWeight(480)
  2550. .layoutWeight(1)
  2551. Toggle({ type: ToggleType.Switch, isOn: this.isShowPrecious })
  2552. .selectedColor(this.themeColor)
  2553. .switchPointColor(Color.White)
  2554. .margin({ right: 18 })
  2555. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2556. .onChange((checked: boolean) => {
  2557. this.isShowPrecious = checked;
  2558. PreferencesUtil.put('isShowPrecious', this.isShowPrecious)
  2559. this.sendChangeEvent()
  2560. })
  2561. .width(50)
  2562. .height(30);
  2563. }
  2564. .height(55)
  2565. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2566. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2567. // 播放页返回键
  2568. Row() {
  2569. SymbolGlyph($r('sys.symbol.arrow_left'))
  2570. .fontSize(20)
  2571. .fontColor([this.themeColor])
  2572. .alignSelf(ItemAlign.Center)
  2573. .margin({ left: 15 })
  2574. Text('播放页返回键')
  2575. .margin({ left: 8 })
  2576. .fontSize(15)
  2577. .fontColor(Color.Gray)
  2578. .fontWeight(480)
  2579. .layoutWeight(1)
  2580. Toggle({ type: ToggleType.Switch, isOn: this.isShowPlayPageBack })
  2581. .selectedColor(this.themeColor)
  2582. .switchPointColor(Color.White)
  2583. .margin({ right: 18 })
  2584. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2585. .onChange((checked: boolean) => {
  2586. this.isShowPlayPageBack = checked;
  2587. PreferencesUtil.put(SettingPage.IS_SHOW_PLAYPAGE_BACK, this.isShowPlayPageBack)
  2588. this.sendChangeEvent()
  2589. })
  2590. .width(50)
  2591. .height(30);
  2592. }
  2593. .height(55)
  2594. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2595. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2596. // // 自动隐藏进度条两侧的按钮
  2597. // Row() {
  2598. // SymbolGlyph($r('sys.symbol.sun_max'))
  2599. // .fontSize(20)
  2600. // .fontColor([this.themeColor])
  2601. // .alignSelf(ItemAlign.Center)
  2602. // .margin({ left: 15 })
  2603. // Text('自动隐藏进度条两侧的按钮')
  2604. // .margin({ left: 8 })
  2605. // .fontSize(15)
  2606. // .fontColor(Color.Gray)
  2607. // .fontWeight(480)
  2608. // .layoutWeight(1)
  2609. // Toggle({ type: ToggleType.Switch, isOn: this.is_auto_hide_progress })
  2610. // .selectedColor(this.themeColor)
  2611. // .switchPointColor(Color.White)
  2612. // .margin({ right: 18 })
  2613. // .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2614. // .onChange((checked: boolean) => {
  2615. // this.is_auto_hide_progress = checked;
  2616. // PreferencesUtil.put(SettingPage.IS_AUTO_HIDE_PROGRESS, this.is_auto_hide_progress)
  2617. // this.sendChangeEvent()
  2618. // })
  2619. // .width(50)
  2620. // .height(30);
  2621. // }
  2622. // .height(55)
  2623. // .clickEffect({ level: ClickEffectLevel.HEAVY })
  2624. //
  2625. // Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2626. // 显示我的收藏
  2627. Row() {
  2628. SymbolGlyph($r('sys.symbol.heart'))
  2629. .fontSize(20)
  2630. .fontColor([this.themeColor])
  2631. .alignSelf(ItemAlign.Center)
  2632. .margin({ left: 15 })
  2633. Text('显示我的收藏')
  2634. .margin({ left: 8 })
  2635. .fontSize(15)
  2636. .fontColor(Color.Gray)
  2637. .fontWeight(480)
  2638. .layoutWeight(1)
  2639. Toggle({ type: ToggleType.Switch, isOn: this.isShowFAV })
  2640. .selectedColor(this.themeColor)
  2641. .switchPointColor(Color.White)
  2642. .margin({ right: 18 })
  2643. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2644. .onChange((checked: boolean) => {
  2645. this.isShowFAV = checked;
  2646. PreferencesUtil.put(SettingPage.IS_SHOW_FAV, this.isShowFAV)
  2647. this.sendChangeEvent()
  2648. })
  2649. .width(50)
  2650. .height(30);
  2651. }
  2652. .height(55)
  2653. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2654. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2655. // 显示最近播放
  2656. Row() {
  2657. SymbolGlyph($r('sys.symbol.clock'))
  2658. .fontSize(20)
  2659. .fontColor([this.themeColor])
  2660. .alignSelf(ItemAlign.Center)
  2661. .margin({ left: 15 })
  2662. Text('显示最近播放')
  2663. .margin({ left: 8 })
  2664. .fontSize(15)
  2665. .fontColor(Color.Gray)
  2666. .fontWeight(480)
  2667. .layoutWeight(1)
  2668. Toggle({ type: ToggleType.Switch, isOn: this.isShowHistory })
  2669. .selectedColor(this.themeColor)
  2670. .switchPointColor(Color.White)
  2671. .margin({ right: 18 })
  2672. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2673. .onChange((checked: boolean) => {
  2674. this.isShowHistory = checked;
  2675. PreferencesUtil.put(SettingPage.IS_SHOW_HISTORY, this.isShowHistory)
  2676. this.sendChangeEvent()
  2677. })
  2678. .width(50)
  2679. .height(30);
  2680. }
  2681. .height(55)
  2682. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2683. }
  2684. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  2685. .animation({ duration: 500, curve: Curve.Ease, delay: 600 }))
  2686. .backgroundColor($r('app.color.settings_background_main'))
  2687. .borderRadius(20)
  2688. .margin({
  2689. left: 0,
  2690. right: 0,
  2691. top: 10,
  2692. bottom: 20
  2693. })
  2694. .padding(0)
  2695. }
  2696. @Builder
  2697. jcBuilder() {
  2698. //设置教程
  2699. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  2700. Column() {
  2701. Row() {
  2702. SymbolGlyph($r('sys.symbol.hand_draw'))
  2703. .fontSize(20)
  2704. .fontColor([this.themeColor])
  2705. .alignSelf(ItemAlign.Center)
  2706. .margin({ left: 15 })
  2707. Text('设置教程:')
  2708. .margin({ left: 8 })
  2709. .fontSize(15)
  2710. .fontColor(Color.Gray)
  2711. .fontWeight(480)
  2712. Text('点击进Q群讨论')
  2713. .margin({ right: 10 })
  2714. .fontSize(15)
  2715. .fontColor(Color.Gray)
  2716. .layoutWeight(1)
  2717. Blank()
  2718. // 右侧箭头
  2719. Image($r('app.media.arrow_right'))
  2720. .width(22)
  2721. .height(22)
  2722. .margin({ left: 20, right: 20 })
  2723. .align(Alignment.Center)
  2724. }
  2725. .height(55)
  2726. }
  2727. }
  2728. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2729. .onClick(() => {
  2730. const qqUrl =
  2731. `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${CommonConstants.QQ_GROUP}&card_type=group&source=external`
  2732. let context = this.getUIContext().getHostContext() as common.UIAbilityContext
  2733. context.openLink(qqUrl, {})
  2734. })
  2735. .backgroundColor($r('app.color.settings_background_main'))
  2736. .borderRadius(15)
  2737. .margin({ top: 0, bottom: 20 })
  2738. .padding(0)
  2739. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  2740. .animation({ duration: 500, curve: Curve.Ease, delay: 220 }))
  2741. }
  2742. @Builder
  2743. apiBuilder() {
  2744. // API设置分组
  2745. Column() {
  2746. Row() {
  2747. Text(){
  2748. Span('API设置')
  2749. Span('\n(请注意:使用此功能您需拥有相关著作人的授权,否则可能导致版权法律纠纷,本软件不提供任何API,本软件对此不负任何责任。)')
  2750. .fontColor(this.themeColor).fontSize(14)
  2751. // .fontStyle(FontStyle.Italic)
  2752. }
  2753. .margin({ left: 18, right: 20 })
  2754. .fontSize(16)
  2755. .fontColor(Color.Gray)
  2756. .fontWeight(480)
  2757. .layoutWeight(1)
  2758. }
  2759. .height(82)
  2760. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2761. // 歌词API
  2762. Button({ type: ButtonType.Normal, stateEffect: true }) {
  2763. Row() {
  2764. SymbolGlyph($r('sys.symbol.lightbulb'))
  2765. .fontSize(20)
  2766. .fontColor([this.themeColor])
  2767. .alignSelf(ItemAlign.Center)
  2768. .margin({ left: 15 })
  2769. Text('歌词:')
  2770. .margin({ left: 8, right: 6 })
  2771. .fontSize(15)
  2772. .fontColor(Color.Gray)
  2773. Text(this.lyricApiUrl)
  2774. .margin({ right: 10 })
  2775. .fontSize(15)
  2776. .fontColor(Color.Gray)
  2777. .layoutWeight(1)
  2778. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  2779. .width(20)
  2780. .height(20)
  2781. .margin({ right: 18 })
  2782. }
  2783. }
  2784. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2785. .backgroundColor(Color.Transparent)
  2786. .onClick(() => {
  2787. this.apiDialogType = 'lyric'
  2788. this.tempApiUrl = this.lyricApiUrl
  2789. this.apiDialogController.open()
  2790. })
  2791. .height(55)
  2792. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  2793. // 封面API
  2794. Button({ type: ButtonType.Normal, stateEffect: true }) {
  2795. Row() {
  2796. SymbolGlyph($r('sys.symbol.picture'))
  2797. .fontSize(20)
  2798. .fontColor([this.themeColor])
  2799. .alignSelf(ItemAlign.Center)
  2800. .margin({ left: 15 })
  2801. Text('封面:')
  2802. .margin({ left: 8, right: 6 })
  2803. .fontSize(15)
  2804. .fontColor(Color.Gray)
  2805. Text(this.coverApiUrl)
  2806. .margin({ right: 10 })
  2807. .fontSize(15)
  2808. .fontColor(Color.Gray)
  2809. .layoutWeight(1)
  2810. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  2811. .width(20)
  2812. .height(20)
  2813. .margin({ right: 18 })
  2814. }
  2815. }
  2816. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2817. .backgroundColor(Color.Transparent)
  2818. .onClick(() => {
  2819. this.apiDialogType = 'cover'
  2820. this.tempApiUrl = this.coverApiUrl
  2821. this.apiDialogController.open()
  2822. })
  2823. .height(55)
  2824. }
  2825. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  2826. .animation({ duration: 500, curve: Curve.Ease, delay: 200 }))
  2827. .backgroundColor($r('app.color.settings_background_main'))
  2828. .borderRadius(20)
  2829. .margin({
  2830. left: 0,
  2831. right: 0,
  2832. top: 10,
  2833. bottom: 20
  2834. })
  2835. .padding(0)
  2836. }
  2837. @Builder
  2838. customizeICONSheet() {
  2839. Scroll() {
  2840. Column() {
  2841. CustomizeICON({
  2842. iconIndex:this.iconCurrentID,
  2843. iconArray:this.iconArray,
  2844. onIconChange:(iconId:string,iconUrl:string)=>{
  2845. this.iconCurrentID = iconId
  2846. PreferencesUtil.put('iconCurrentID', this.iconCurrentID)
  2847. PreferencesUtil.put('iconCurrentUrl', iconUrl)
  2848. this.sendChangeEvent()
  2849. }
  2850. })
  2851. }
  2852. }
  2853. .width('100%')
  2854. .height('100%')
  2855. }
  2856. //发送广播通知更新UI
  2857. sendChangeEvent() {
  2858. const eventData: emitter.EventData = {};
  2859. emitter.emit({ eventId: EventConstants.EVENT_SETTING_UPDATE }, eventData); // 发送广播通知更新doSwipBack
  2860. }
  2861. goSelectImage() {
  2862. let selectUris: Array<string> = [];
  2863. let photoPicker = new photoAccessHelper.PhotoViewPicker();
  2864. let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  2865. photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
  2866. photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
  2867. photoPicker.select(photoSelectOptions).then(async (photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
  2868. //用一个全局变量存储返回的uri
  2869. selectUris = photoSelectResult.photoUris;
  2870. console.info('photoViewPicker.select to file succeed and uris are:' + selectUris);
  2871. //使用fs.openSync接口,通过uri打开这个文件得到fd
  2872. let file = fileIo.openSync(selectUris[0], fileIo.OpenMode.READ_ONLY);
  2873. console.info('file fd: ' + file.fd);
  2874. const timestamp: number = Math.floor(Date.now() / 1000);
  2875. let name = timestamp + "_homebg"
  2876. let imagePath = this.context.filesDir + FileUtil.separator + name
  2877. imagePath = fileUri.getUriFromPath(imagePath)
  2878. let file2 = fileIo.openSync(imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
  2879. fileIo.copyFileSync(file.fd, file2.fd)
  2880. fileIo.closeSync(file);
  2881. fileIo.closeSync(file2);
  2882. this.customizeBgPath = imagePath
  2883. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG_PATH, this.customizeBgPath)
  2884. this.sendChangeEvent()
  2885. }).catch((err: BusinessError) => {
  2886. console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
  2887. })
  2888. }
  2889. @Builder
  2890. customizeBgSheet() {
  2891. Scroll() {
  2892. Column() {
  2893. this.CustomizeBg()
  2894. }
  2895. }
  2896. .width('100%')
  2897. .height('100%')
  2898. }
  2899. @Builder
  2900. CustomizeBg() {
  2901. Column() {
  2902. Image(this.customizeBgPath)
  2903. .height('42%')
  2904. .alt($r('app.media.add_image2'))
  2905. .objectFit(ImageFit.Contain)
  2906. .borderRadius(15)
  2907. .clip(true)
  2908. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2909. .blur(this.blurValue)
  2910. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.6})
  2911. .brightness(this.bgBrightness + 0.8)
  2912. .margin({ left: 30, right: 30, bottom: 20 })
  2913. .onClick(async () => {
  2914. this.goSelectImage()
  2915. })
  2916. Row() {
  2917. Row() {
  2918. Button('选择图片')
  2919. .fontColor(Color.White)
  2920. .fontSize(12)
  2921. .height(48)
  2922. .width(100)
  2923. .clickEffect({ level: ClickEffectLevel.HEAVY })
  2924. .backgroundColor(this.themeColor)
  2925. .stateEffect(true)
  2926. .onClick(async () => {
  2927. this.goSelectImage()
  2928. })
  2929. }
  2930. .height('100%')
  2931. .justifyContent(FlexAlign.Center)
  2932. .layoutWeight(1)
  2933. }
  2934. .width('100%')
  2935. .height(58)
  2936. .margin({ bottom: 20 })
  2937. Column() {
  2938. Row() {
  2939. Text('自定义背景:')
  2940. .margin({ left: 18 })
  2941. .fontSize(15)
  2942. .fontColor($r('app.color.text_color'))
  2943. .fontWeight(480)
  2944. .layoutWeight(1)
  2945. Toggle({ type: ToggleType.Switch, isOn: this.isCustomizeBg })
  2946. .selectedColor(this.themeColor)
  2947. .switchPointColor(Color.White)
  2948. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.5})
  2949. .margin({ right: 18 })
  2950. .onChange((checked: boolean) => {
  2951. this.isCustomizeBg = checked;
  2952. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG, this.isCustomizeBg)
  2953. this.sendChangeEvent()
  2954. })
  2955. .width(50)
  2956. .height(30);
  2957. }
  2958. .height(55)
  2959. }
  2960. .backgroundColor($r('app.color.settings_background_main'))
  2961. .borderRadius(15)
  2962. .margin({
  2963. left: 30,
  2964. right: 30,
  2965. top: 0,
  2966. bottom: 20
  2967. })
  2968. .padding(0)
  2969. Column() {
  2970. Row() {
  2971. Text('背景模糊:')
  2972. .margin({ left: 18 })
  2973. .fontSize(15)
  2974. .fontColor($r('app.color.text_color'))
  2975. .fontWeight(480)
  2976. Slider({
  2977. value: this.blurValue,
  2978. min: 0,
  2979. max: 100,
  2980. step: 1,
  2981. style: SliderStyle.OutSet
  2982. })
  2983. .blockColor(this.themeColor)
  2984. .trackColor($r('app.color.speed_text_color'))
  2985. .selectedColor($r('app.color.index_background'))
  2986. .trackThickness(8)
  2987. .onChange((value: number) => {
  2988. this.blurValue = value;
  2989. PreferencesUtil.put(SettingPage.CUSTOMIZE_BG_BLUR, this.blurValue)
  2990. this.sendChangeEvent()
  2991. })
  2992. .layoutWeight(1)
  2993. }
  2994. .height(55)
  2995. }
  2996. .backgroundColor($r('app.color.settings_background_main'))
  2997. .borderRadius(15)
  2998. .margin({
  2999. left: 30,
  3000. right: 30,
  3001. top: 0,
  3002. bottom: 20
  3003. })
  3004. .padding(0)
  3005. Column() {
  3006. Row() {
  3007. Text('背景亮度:')
  3008. .margin({ left: 18 })
  3009. .fontSize(15)
  3010. .fontColor($r('app.color.text_color'))
  3011. .fontWeight(480)
  3012. Slider({
  3013. value: this.bgBrightness,
  3014. min: -0.4,
  3015. max: 0.4,
  3016. step: 0.1,
  3017. style: SliderStyle.OutSet
  3018. })
  3019. .blockColor(this.themeColor)
  3020. .trackColor($r('app.color.speed_text_color'))
  3021. .selectedColor($r('app.color.index_background'))
  3022. .trackThickness(8)
  3023. .onChange((value: number) => {
  3024. this.bgBrightness = value;
  3025. PreferencesUtil.put(SettingPage.BG_BRIGHTNESS, this.bgBrightness)
  3026. this.sendChangeEvent()
  3027. })
  3028. .layoutWeight(1)
  3029. }
  3030. .height(55)
  3031. }
  3032. .backgroundColor($r('app.color.settings_background_main'))
  3033. .borderRadius(15)
  3034. .margin({
  3035. left: 30,
  3036. right: 30,
  3037. top: 0,
  3038. bottom: 20
  3039. })
  3040. .padding(0)
  3041. }
  3042. .margin({ bottom: 30 })
  3043. }
  3044. // 判断当前主题色是否为自定义色
  3045. isCustomThemeColor(): boolean {
  3046. for (let i = 0; i < SettingPage.THEME_COLOR_LIST.length - 1; i++) {
  3047. if (SettingPage.THEME_COLOR_LIST[i].color === this.themeColor) {
  3048. return false;
  3049. }
  3050. }
  3051. return true;
  3052. }
  3053. // 会员功能弹窗
  3054. showVipDialog() {
  3055. DialogHelper.showCustomContentDialog({
  3056. dialogId: 'vip',
  3057. title: "友情提示",
  3058. autoCancel: false,
  3059. backCancel: true,
  3060. contentBuilder: () => {
  3061. this.customVipBuilder("该功能需开通会员,非常感谢您的支持!")
  3062. },
  3063. buttons: [],
  3064. })
  3065. }
  3066. @Builder
  3067. customVipBuilder(content: string) {
  3068. Column() {
  3069. Text(content)
  3070. .fontColor(Color.Gray)
  3071. .fontSize(16)
  3072. .alignSelf(ItemAlign.Start)
  3073. .margin({ bottom: 15 })
  3074. Row() {
  3075. Button('取消')
  3076. .fontColor(Color.White)
  3077. .backgroundColor(this.themeColor)
  3078. .height(50)
  3079. .layoutWeight(1)
  3080. .stateEffect(true)
  3081. .margin({ right: 6 })
  3082. .onClick(() => {
  3083. DialogHelper.closeDialog('vip');
  3084. })
  3085. Button('开通')
  3086. .fontColor(Color.White)
  3087. .layoutWeight(1)
  3088. .height(50)
  3089. .backgroundColor(this.themeColor)
  3090. .stateEffect(true)
  3091. .margin({ left: 6 })
  3092. .onClick(() => {
  3093. this.isThemeSheet = false;
  3094. DialogHelper.closeDialog('vip');
  3095. this.mType = 1//跳转到用户中心
  3096. // router.pushUrl({
  3097. // url: 'pages/UserCenter'
  3098. // }, router.RouterMode.Single);
  3099. })
  3100. }
  3101. }
  3102. .width("100%")
  3103. .padding(10)
  3104. }
  3105. @State appIdentifier:string=''
  3106. geIDD() {
  3107. // 获取应用签名等信息示例代码
  3108. let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
  3109. bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
  3110. try {
  3111. bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
  3112. hilog.info(0x0000, 'testTag11', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data));
  3113. let inde = JSON.stringify(data)
  3114. this.appIdentifier = inde.substring(inde.indexOf('appIdentifier'),inde.indexOf('"certificate'))
  3115. hilog.info(0x0000, 'testTag11', 'appIdentifier Data: %{public}s', this.appIdentifier);
  3116. }).catch((err: BusinessError) => {
  3117. hilog.error(0x0000, 'testTag11', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
  3118. });
  3119. } catch (err) {
  3120. let message = (err as BusinessError).message;
  3121. hilog.error(0x0000, 'testTag33', 'getBundleInfoForSelf failed: %{public}s', message);
  3122. }
  3123. }
  3124. private getMeituConfig(): UploadConfig | null {
  3125. // 尝试清理可能存在的旧token缓存,避免使用过期token
  3126. try {
  3127. PreferencesUtil.put(SettingPage.MEITU_UPLOAD_TOKEN_KEY, '')
  3128. LogUtil.info('SettingPage', '已清理旧的UpToken缓存')
  3129. } catch (error) {
  3130. LogUtil.debug('SettingPage', '清理token缓存失败,继续生成新token')
  3131. }
  3132. // 每次都生成新的UpToken,避免使用过期token
  3133. LogUtil.info('SettingPage', `生成新的UpToken,Bucket: ${SettingPage.MEITU_BUCKET}`)
  3134. const token = UpTokenUtil.generateUpToken(SettingPage.MEITU_AK, SettingPage.MEITU_SK, SettingPage.MEITU_BUCKET, 3600)
  3135. LogUtil.info('SettingPage', `UpToken生成完成,Token前缀: ${token.substring(0, 20)}...`)
  3136. // Domain可以缓存,因为通常不会变化
  3137. let domain = PreferencesUtil.getStringSync(SettingPage.MEITU_UPLOAD_DOMAIN_KEY, SettingPage.MEITU_DOMAIN)
  3138. if (!domain || domain.trim().length === 0) {
  3139. domain = SettingPage.MEITU_DOMAIN
  3140. PreferencesUtil.put(SettingPage.MEITU_UPLOAD_DOMAIN_KEY, domain)
  3141. }
  3142. if (!domain || domain.trim().length === 0) {
  3143. LogUtil.warn('SettingPage', '日志上传未配置域名')
  3144. return null
  3145. }
  3146. LogUtil.info('SettingPage', `上传配置 - Domain: ${domain}, Bucket: ${SettingPage.MEITU_BUCKET}`)
  3147. return {
  3148. uploadToken: token,
  3149. domain: domain,
  3150. keyPrefix: 'logs'
  3151. }
  3152. }
  3153. private ensureMeituUploadHandler(isInit: boolean): boolean {
  3154. const config = this.getMeituConfig()
  3155. if (!config) {
  3156. if (!isInit) {
  3157. ToastUtil.showToast('未配置日志上传token/域名,已关闭开关')
  3158. this.isLogUploadEnabled = false
  3159. PreferencesUtil.put(SettingPage.LOG_UPLOAD_ENABLED, false)
  3160. }
  3161. this.registerLogUploadDisabled()
  3162. return false
  3163. }
  3164. LogCollector.registerUploadHandler(async (filePath: string): Promise<string> => {
  3165. return await Uploader.uploadFile(filePath, config)
  3166. })
  3167. return true
  3168. }
  3169. private registerLogUploadDisabled() {
  3170. LogCollector.registerUploadHandler(async (filePath: string): Promise<void> => {
  3171. LogUtil.info('LogUpload', `日志上传开关关闭,跳过: ${filePath}`)
  3172. return
  3173. })
  3174. }
  3175. }
  3176. // 主题色类型声明
  3177. export interface ThemeColorItem {
  3178. name: string;
  3179. color: string;
  3180. isVip: boolean;
  3181. }
  3182. // 工具函数:将一维数组分成每行2个的二维数组
  3183. function chunkArray<T>(arr: Array<T>, size: number): Array<Array<T>> {
  3184. const result: Array<Array<T>> = [];
  3185. for (let i = 0; i < arr.length; i += size) {
  3186. const row: Array<T> = [];
  3187. for (let j = 0; j < size; j++) {
  3188. if (i + j < arr.length) {
  3189. row.push(arr[i + j]);
  3190. }
  3191. }
  3192. result.push(row);
  3193. }
  3194. return result;
  3195. }