| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329 |
- import { AppUtil, ArrayUtil, DeviceUtil, DisplayUtil, LogUtil, PreferencesUtil,
- StrUtil,
- ToastUtil } from '@pura/harmony-utils';
- import TitleBar from '../view/TitleBar';
- import { curves,
- ImmersiveMode,
- LengthMetrics,
- LevelMode,
- MenuModifier,
- router, SegmentButton, SegmentButtonOptions, SymbolGlyphModifier } from '@kit.ArkUI';
- import mainViewModel, { MainViewModel } from '../viewmodel/MainViewModel';
- import ItemData from '../viewmodel/ItemData';
- import type { sysResource } from '../viewmodel/ItemData';
- import { CommonConstants } from '../common/constants/CommonConstants';
- import { EventConstants } from '../common/constants/EventConstants';
- import { VideoItem } from '../viewmodel/VideoItem';
- import ScreenUtil from '../common/util/ScreenUtil';
- import { Utility } from '../common/util/Utility';
- import { BusinessError, emitter } from '@kit.BasicServicesKit';
- import { common } from '@kit.AbilityKit';
- import { BreakpointSystem, BreakpointTypeEnum } from '../common/util/BreakpointSystem';
- import dataStorage from '@ohos.data.storage';
- import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
- import { SettingPage } from './SettingPage';
- import { deviceInfo } from '@kit.BasicServicesKit';
- import { resourceManager } from '@kit.LocalizationKit';
- import { systemShare } from '@kit.ShareKit';
- import { uniformTypeDescriptor } from '@kit.ArkData';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- import { DialogHelper, DialogAction } from '@pura/harmony-dialog';
- import UserUtil from '../common/util/UserUtil';
- import json from '@ohos.util.json';
- import { UserCenter } from './UserCenter';
- import { ScanFilePage } from './ScanFilePage';
- import { AboutPage, gotoShare } from './AboutPage';
- import { smartMobilityCommon } from '@kit.CarKit';
- import { UpdateLogManager } from '../common/util/UpdateLogManager';
- import OnlineUpdateLogDialog from '../dialog/OnlineUpdateLog';
- import OnlineUpdateLog from '../dialog/OnlineUpdateLog';
- import { LocalMusic } from '../view/LocalMusic';
- import { ChartsCount } from './ChartsCount';
- import { image } from '@kit.ImageKit';
- import { Playlist, PlaylistSong } from '../viewmodel/Playlist';
- import PlaylistTable from '../common/util/PlaylistTable';
- import { convertPlaylistSongsToVideoItems } from './PlaylistDetailPage';
- import MediaTable from '../common/util/MediaTable';
- import { showCreatePlaylistDialog } from '../dialog/PlaylistDialog';
- import { ImagePickerUtil } from '../common/util/ImagePickerUtil';
- import { WebDavMainPage } from './WebDavMainPage';
- import { WebDavAccount } from '../viewmodel/WebDavAccount';
- import { RemoteDriveManager } from '../common/util/RemoteDriveManager';
- import { getCloudDiskIcon, RemoteDriveAccountDialog } from '../dialog/RemoteDriveAccountDialog';
- import ReqPermissionUtil from '../common/util/ReqPermissionUtil';
- import { getRemoteDriveAccountLabel, getRemoteDriveDisplayLabel, getRemoteDriveProtocolLabel } from '../common/util/RemoteDriveLabel';
- import { RemoteDriveType } from '../common/enums/RemoteDriveType';
- import { RemoteMusicPage } from '../view/RemoteMusicPage';
- import { ServerLogUtil } from '../common/util/ServerLogUtil';
- import { PlayStatus } from '../common/PlayStatus';
- import { PointLightDefaultButton } from '../view/PointLight/PointLightDeFaultButton';
- import { FindView } from '../view/FindView';
- import { hdsEffect } from '@kit.UIDesignKit';
- // import { FFmpeg, FFProgressMessageParser } from '@sj/ffmpeg';
- const TAG = 'NewIndex'; // 日志标签
- /**
- * 首页主组件,包含顶部标题栏、主内容区(本地音乐/网络内容)、侧边抽屉菜单等。
- * 支持多端适配、广告集成、导航、生命周期管理等功能。
- */
- @Preview
- @Entry
- @Component
- struct NewIndex {
- //背景流光控制器
- @State bgController: hdsEffect.ShaderEffectController|undefined = deviceInfo.sdkApiVersion>=20
- &&canIUse("SystemCapability.UIDesign.HDSComponent.Core")?
- new hdsEffect.ShaderEffectController():undefined;
- @State defalut_home_type:number = 0//首页默认类型 可支持首页 媒体库 歌单 网盘
- @State isDetailView: boolean = false; // 是否在艺术家/专辑详情视图
- @Provide isShowPlay: boolean = false;
- @Provide CONTROL_PlayStatus: number = PlayStatus.INIT;
- @Provide progressValue: number = 0;
- @State isShowPrecious: boolean = false //播控条显示上一首按钮
- @State bottomBarHeight: number = 70;
- @StorageProp('bottomSafeHeight') bottomSafeHeight: number = 0;
- @Provide cover: string | undefined = '';
- // @Provide currentSong: VideoItem | undefined = undefined;
- @StorageLink('currentSong') currentSong: VideoItem | undefined = undefined;
- @Provide isMultiSelect: boolean = false;
- /** 页面上下文 */
- context = this.getUIContext().getHostContext() as common.UIAbilityContext
- @Provide currentSongListName:string = '' //当前歌单名称
- @Provide currentSongListID:string='' //当前歌单ID
- @State isDarkMode: boolean = false
- /** 列表滚动器,用于抽屉菜单列表滚动 */
- private scroller: Scroller = new Scroller();
- /** 应用包名 */
- @State bundleName: string = ''
- @State appName: string = ''
- /** 是否显示侧边抽屉菜单 */
- @Provide isShowDrawer: boolean = false;
- /** 抽屉菜单 X 轴偏移量,用于手势滑动动画 */
- @Provide offsetX: number = 0;
- @StorageProp('findCanBack') findCanBack: boolean = false
- /** 本地视频列表,页面参数传入 */
- @Provide videoLocalList: Array<VideoItem> = []
- /** Y 轴偏移量(预留) */
- @State offsetY: number = 0;
- /** 主内容类型(0:本地音乐,1:网络内容) */
- @Provide mType: number = 0
- /** 模式类型(如文件夹 媒体库 艺术家、专辑等) */
- @Provide modeType: number = 0
- /** 是否为零状态(预留) */
- @Provide('isZero') isZero: boolean = false;
- /** 是否显示赞助入口 */
- @State isShowSponsorship: boolean = false
- /** 音乐是否为零状态(预留) */
- @Provide('isMusicZero') isMusicZero: boolean = false;
- @State isShowTitleBar: boolean = false //是否显示分类导航条
- /** 本地音乐列表,持久化存储 */
- @StorageLink('musicLocalList') musicLocalList: Array<VideoItem> = []
- @Provide isFavMusic: boolean = false
- @StorageProp('windowWidth') windowWidth: number = 0;
- @StorageProp('windowHeight') windowHeight: number = 0;
- @StorageProp('isHiCarStatus') isHiCarStatus: boolean = false;
- @StorageProp('curDisplayIsHiCar') curDisplayIsHiCar: boolean = false;
- /**
- * 是否显示更新日志开关
- */
- @State isShowUpdateDialog: boolean = false
- /** 应用版本号 */
- @State versionName: string = ''
- /** 音频根目录路径 */
- @Provide rootPath: string = ''
- /** 当前路径 */
- @Provide currentPath: string = ''
- /** 是否为历史记录页面 */
- @Provide isHistory: boolean = false
- /** 是否可以返回上一级 */
- @Provide isCanBack: boolean = false
- @StorageProp('currentColorMode') currentMode: number = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
- @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR;
- /**
- * 一多界面适配断点系统
- */
- private breakpointSystem: BreakpointSystem = new BreakpointSystem();
- /** 当前断点类型(如大屏/小屏) */
- @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
- /** 记录上一次点击返回键的时间戳,用于双击退出 */
- private backTime: number = 0;
- @State tabOptions: SegmentButtonOptions = SegmentButtonOptions.tab({
- buttons: [{ text: '分类' }, { text: '歌单' }, { text: '网盘' }],
- direction: Direction.Ltr,
- backgroundColor: $r('app.color.index_background'),
- selectedBackgroundColor:$r('app.color.start_window_background'),
- selectedFontColor: $r('app.color.text_color'),
- localizedTextPadding: {
- end: LengthMetrics.vp(10),
- start: LengthMetrics.vp(10)
- }
- })
- @State @Watch('tabSelectedIndexesChanged') tabSelectedIndexes: number[] = [0]
- //当胶囊按钮的选择发生变化时调用此函数
- tabSelectedIndexesChanged() {
- if(this.tabSelectedIndexes[0]==1){
- this.mType = 0
- } else if(this.tabSelectedIndexes[0]==2){
- // 网盘选项卡
- if(this.webDavAccounts.length>0&&(this.webDavAccounts[0].webType===RemoteDriveType.Navidrome||
- this.webDavAccounts[0].webType===RemoteDriveType.Jellyfin||
- this.webDavAccounts[0].webType===RemoteDriveType.Emby||
- this.webDavAccounts[0].webType===RemoteDriveType.DaoLiYu)){
- this.mType = 7
- }else{
- this.mType = 6
- }
- }
- }
- // 歌单相关状态变量
- @State playlistList: Playlist[] = []
- @State isShowCreatePlaylistDialog: boolean = false
- @State selectedPlaylist: Playlist | null = null
- private playlistTable: PlaylistTable | null = null
- // 网盘账户相关状态变量
- @State webDavAccounts: WebDavAccount[] = []
- private webdavManager: RemoteDriveManager = RemoteDriveManager.getInstance()
- private _webDavLoading: boolean = false // 防止重复加载网盘账户的标志
- @State selectedAccount: WebDavAccount = new WebDavAccount()
- /**
- * 返回键处理逻辑:
- * - 如果不是根目录或有历史记录,发送广播通知更新列表
- * - 如果是根目录,双击返回键退出应用,否则提示
- */
- onBackPress(): boolean | void {
- console.info('onecold onBackPress isDetailView = '+ this.isDetailView);
- console.info('onecold onBackPress mType = '+ this.mType);
- if (this.mType === 4) {
- this.returnToConfiguredHome()
- } else if (this.currentPath !== this.rootPath || this.isHistory || this.isFavMusic ||
- (this.modeType !== 0 && this.isCanBack)) {
- console.info('onecold 返回键处理逻辑:发送音频广播通知更新列表');
- const eventData: emitter.EventData = {};
- emitter.emit({ eventId: EventConstants.EVENT_SWIPE_BACK_UPDATE }, eventData); // 发送音频广播通知更新doSwipBack
- } else if(this.mType === 7) {
- if(this.isDetailView){
- console.info('onecold RemoteMusicPage 返回键处理:发送手势返回事件');
- const eventData: emitter.EventData = {};
- emitter.emit({ eventId: EventConstants.EVENT_SWIPE_BACK_NAVID}, eventData);
- }else{
- if (this.isShowDrawer) {
- // 如果抽屉菜单打开,先关闭抽屉
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- } else {
- return false
- }
- }
- } else if(this.mType === 6) {
- console.info('onecold 网盘 返回键处理:发送手势返回事件');
- const eventData: emitter.EventData = {};
- emitter.emit({ eventId: EventConstants.EVENT_SWIPE_BACK_DISK }, eventData);
- } else if(this.mType === 8) {
- if (this.findCanBack) {
- const eventData: emitter.EventData = {}
- emitter.emit({ eventId: EventConstants.EVENT_FIND_VIEW_BACK }, eventData)
- } else if (this.isShowDrawer) {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- } else {
- return false
- }
- } else if(this.mType > 0){
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- // 动画闭包内控制Image组件的出现和消失
- // this.isShowDrawer = !this.isShowDrawer
- // this.offsetX = 0
- this.mType = 8
- })
- } else {
- console.info('onecold 返回键处理 关闭');
- if (this.isShowDrawer) {
- // 如果抽屉菜单打开,先关闭抽屉
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- } else {
- return false
- }
- }
- return true;
- }
- /**
- * 刷新@State用户信息变量,确保UI同步
- */
- refreshUserInfoState() {
- this.isLogin = PreferencesUtil.getBooleanSync('isLogin', false);
- this.userId = PreferencesUtil.getNumberSync('userId', 0);
- this.userName = PreferencesUtil.getStringSync('userName', '未登录用户');
- this.userAvatarUrl = PreferencesUtil.getStringSync('userAvatarUrl', '');
- this.subscriptionName = PreferencesUtil.getStringSync('subscriptionName', '');
- this.subscriptionEndDate = PreferencesUtil.getStringSync('subscriptionEndDate', '');
- this.hasActiveSubscription = PreferencesUtil.getBooleanSync('hasActiveSubscription', false);
- }
- onPageShow() {
- LogUtil.info('heanup NewIndex', 'onPageShow 被调用,刷新歌单列表和网盘账户列表')
- // 加载歌单列表
- this.loadPlaylistList()
- // 加载网盘账户列表
- this.loadWebDavAccounts()
- // 通知 LocalMusic 页面已显示,恢复旋转
- AppStorage.setOrCreate('isPageVisible', true)
- }
- onPageHide() {
- // 通知 LocalMusic 页面已隐藏,停止旋转
- AppStorage.setOrCreate('isPageVisible', false)
- }
- /**
- * 页面显示生命周期钩子
- * - 注册断点系统
- * - 获取页面参数
- * - 设置状态栏样式
- * - 初始化图片缓存
- * - 判断是否显示赞助入口
- */
- async aboutToAppear() {
- this.defalut_home_type = PreferencesUtil.getNumberSync('defalut_home_type', 0)
- this.isShowPrecious = PreferencesUtil.getBooleanSync('isShowPrecious', false)
- ReqPermissionUtil.reqPermissionsFromUser(ReqPermissionUtil.permissions, this.context);
- this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, false)
- Utility.enableFullScreen()
- this.topRectHeight = px2vp(AppUtil.getStatusBarHeight());
- Utility.getAppName(getContext(this)).then((appName: string) => {
- this.appName = appName
- })
- this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
- this.breakpointSystem.register();
- let params = router.getParams() as Record<string, Object>;
- if (params && params.videoList) {
- this.videoLocalList = params.videoList as VideoItem[];
- LogUtil.info('heanup NewIndex', '从路由参数获取到播放列表,长度:' + this.videoLocalList.length)
- } else {
- this.videoLocalList = []
- LogUtil.info('heanup NewIndex', '路由参数中没有播放列表,使用空数组')
- }
- // 检查是否从WebDavPage返回
- if (params && params.fromWebDavPage) {
- LogUtil.info('heanup NewIndex', '从WebDavPage返回,切换到网盘标签页')
- this.mType = 6
- this.tabSelectedIndexes = [2] // 切换到网盘标签
- }
- // Utility.setStatusBarLight()
- ScreenUtil.setScreenSize();
- this.bundleName = AppUtil.getBundleName()
- this.versionName = AppUtil.getVersionName();
- // await ImageKnife.getInstance().initFileCache(this.context, 256, 256 * 1024 * 1024)
- this.isShowSponsorship = Utility.isOpenTime()
- let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
- hilog.info(0x0000, 'Heanup', '当前 NewIndex themeColor:' + themeColor);
- AppStorage.setOrCreate('themeColor', themeColor);
- this.themeColor = themeColor
- // ====== 本地会员同步提醒逻辑 ======
- // this.refreshUserInfoState();
- // if (this.isLogin) {
- // void this.fetchUserInfo();
- // }
- await UserUtil.fetchUserInfo();
- this.refreshUserInfoState();
- let changeUserState: emitter.InnerEvent = { eventId: EventConstants.EVENT_USER_STATE_CHANGE }
- emitter.on(changeUserState, () => {
- this.refreshUserInfoState();
- });
- let eventSetting: emitter.InnerEvent = { eventId: EventConstants.EVENT_SETTING_UPDATE }
- // 监听广播事件(通用设置配置更新)
- emitter.on(eventSetting, (eventData: emitter.EventData) => {
- this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, true)
- });
- emitter.on({ eventId: EventConstants.EVENT_SETTING_BACK_TO_HOME }, () => {
- this.returnToConfiguredHome()
- });
- this.logHiCar('info', `getHiCarStatus isHiCarStatus=${this.isHiCarStatus}`)
- if(this.curDisplayIsHiCar||this.isBigScreen()){
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = true
- this.offsetX = 0
- })
- this.isShowTitleBar = false
- }
- // 检查并显示更新日志
- this.checkAndShowUpdateLog();
- // 初始化歌单数据库
- await this.initPlaylistTable();
- // 初始化WebDAV管理器
- await this.initWebDavManager();
- // 监听歌单刷新事件
- emitter.on({ eventId: EventConstants.EVENT_PLAYLIST_REFRESH }, (eventData: emitter.EventData) => {
- LogUtil.info('heanup NewIndex', '收到歌单刷新事件,开始刷新歌单列表')
- this.loadPlaylistList()
- });
- if(Utility.isOpenTime()&&!PreferencesUtil.getBooleanSync('isShowHaoPingDialog17', false)){
- setTimeout(()=>{
- Utility.showHaoPingDialog(this.getUIContext(),this.context,this.appName,this.bundleName)
- PreferencesUtil.putSync('isShowHaoPingDialog17', true)
- },25000)
- }
- this.initDefalutType()
- }
- private initDefalutType(){
- this.applyDefaultHomeState()
- console.info('onecold 网盘 默认首页2 this.mType='+this.mType )
- }
- private isRemoteMusicAccount(account: WebDavAccount | null | undefined): boolean {
- if (!account) {
- return false
- }
- return account.webType === RemoteDriveType.Navidrome
- || account.webType === RemoteDriveType.Jellyfin
- || account.webType === RemoteDriveType.Emby
- || account.webType === RemoteDriveType.AudioStation
- || account.webType === RemoteDriveType.Plex
- || account.webType === RemoteDriveType.DaoLiYu
- }
- private getConfiguredHomeAccount(): WebDavAccount | null {
- const activatedAccount = this.webdavManager.getActivatedWebDavAccount()
- if (activatedAccount) {
- return activatedAccount
- }
- if (this.selectedAccount && (this.selectedAccount.id > 0 || this.selectedAccount.host.length > 0)) {
- return this.selectedAccount
- }
- if (this.webDavAccounts.length > 0) {
- return this.webDavAccounts[0]
- }
- return null
- }
- private applyDefaultHomeState(): void {
- this.defalut_home_type = PreferencesUtil.getNumberSync('defalut_home_type', 0)
- const configuredAccount = this.getConfiguredHomeAccount()
- this.currentSongListID = ''
- this.currentSongListName = ''
- this.modeType = 0
- this.tabSelectedIndexes = [0]
- if(this.defalut_home_type==1){
- this.mType = 0
- this.modeType = 1
- }else if(this.defalut_home_type==2){//如果是网盘的话
- this.tabSelectedIndexes = [2]
- if (configuredAccount) {
- this.selectedAccount = configuredAccount
- }
- this.mType = this.isRemoteMusicAccount(configuredAccount) ? 7 : 6
- }else if(this.defalut_home_type==3){
- this.mType = 0
- this.modeType = 2
- }else if(this.defalut_home_type==4){
- this.mType = 0
- this.modeType = 3
- }else if(this.defalut_home_type==5){
- this.mType = 8
- } else {
- this.mType = 0
- }
- }
- private returnToConfiguredHome(): void {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.applyDefaultHomeState()
- })
- }
- /**
- * 检查并显示更新日志
- */
- private async checkAndShowUpdateLog() {
- try {
- const shouldShow = await UpdateLogManager.checkAndShowUpdateLog();
- if (shouldShow) {
- this.isShowUpdateDialog = !this.isShowUpdateDialog
- UpdateLogManager.markCurrentVersionShown()
- }
- // this.isShowUpdateDialog = true;//调试期间显示更新日志,测试完成后请删除
- } catch (error) {
- console.error('NewIndex checkAndShowUpdateLog error:', error);
- }
- }
- /**
- * 页面消失生命周期钩子
- * 注销断点系统
- */
- aboutToDisappear() {
- console.info('NewIndex aboutToDisappear');
- this.breakpointSystem.unregister();
- emitter.off(EventConstants.EVENT_SWIPE_BACK_UPDATE);
- emitter.off(EventConstants.EVENT_USER_STATE_CHANGE);
- emitter.off(EventConstants.EVENT_SETTING_BACK_TO_HOME);
- // 监听歌单刷新事件
- emitter.off(EventConstants.EVENT_PLAYLIST_REFRESH);
- // 清理WebDAV管理器订阅
- if (this.webdavManager) {
- this.webdavManager.observers = [];
- }
- }
- @Builder
- ContentBuild() {
- Stack() {
- LocalMusic()
- .visibility(this.mType === 0 ? Visibility.Visible : Visibility.None)
- // 本地音乐内容区
- if(this.mType === 1 ){
- UserCenter()
- }else if(this.mType === 2 ){
- ScanFilePage()
- }else if(this.mType === 3 ){
- ChartsCount({
- isShowDrawer:this.isShowDrawer,
- offsetX:this.offsetX
- })
- }else if(this.mType === 4 ){
- SettingPage()
- }else if(this.mType === 5 ){
- AboutPage()
- }else if(this.mType === 8 ){//发现页
- FindView()
- }
- if(this.mType === 6){
- WebDavMainPage({
- offsetX:this.offsetX,
- isShowDrawer:this.isShowDrawer,
- mType:this.mType,
- selectedAccount:this.selectedAccount
- })
- .visibility(this.mType === 6 ? Visibility.Visible : Visibility.None)
- }
- if(this.mType === 7){
- RemoteMusicPage({
- offsetX:this.offsetX,
- isDetailView:this.isDetailView,
- isShowDrawer:this.isShowDrawer,
- mType:this.mType,
- selectedAccount:this.selectedAccount
- })
- .visibility(this.mType === 7 ? Visibility.Visible : Visibility.None)
- }
- // 抽屉打开时的遮罩层,用于拦截点击事件 这个只能正常尺寸的手机竖屏的才能生效
- if (this.isShowDrawer&&this.isPhonePortrait()) {
- Column()
- .width('100%')
- .height('100%')
- .backgroundBlurStyle(BlurStyle.BACKGROUND_THIN)
- .transition(TransitionEffect.OPACITY.animation({
- curve: curves.springMotion(0, 1)
- }))
- .onClick(() => {
- // 点击遮罩层关闭抽屉
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- })
- }
- }
- .bindSheet($$this.isShowUpdateDialog, this.updateSheet(), {
- height: '90%',
- dragBar: true,
- preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
- showClose: true,
- blurStyle: BlurStyle.Regular,
- title: { title: '更新日志' }
- })
- }
- @State private pointLightOptions: hdsEffect.PointLightOptions | undefined = undefined
- build() {
- SideBarContainer(SideBarContainerType.AUTO) {
- Column() {
- this.getLeftView()
- }
- .backgroundColor(Color.Transparent)
- Stack() {
- this.ContentBuild()
- Stack() {
- this.PlayController()
- }
- .width('90%')
- .borderRadius(15)
- .margin({ bottom:DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_2IN1||this.curDisplayIsHiCar
- ? 30 :this.bottomSafeHeight })
- .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
- .backgroundImage(StrUtil.isEmpty(this.cover) ?undefined:this.cover)
- .visibility(this.isMultiSelect||(this.mType>0&&this.mType<6) ? Visibility.None : Visibility.Visible)
- .visualEffect(deviceInfo.sdkApiVersion>=20&&this.bgController&&StrUtil.isEmpty(this.cover)?
- new hdsEffect.HdsEffectBuilder()
- .shaderEffect({
- effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
- animation: {
- duration: 10000,
- iterations: -1,
- autoPlay: true,
- onFinish: ()=> {
- console.info('Succeeded in finishing');
- }
- },
- controller: this.bgController,
- })
- .buildEffect():null)
- .backgroundImageSize( { width: '100%' })
- .animation({
- duration: 500,
- curve: Curve.Friction // 可选动画曲线
- })
- .opacity(0.99)
- .clickEffect({ level: ClickEffectLevel.HEAVY })
- }
- .alignContent(Alignment.Bottom)
- .width('100%')
- .height('100%')
- .gesture(SwipeGesture({ direction: SwipeDirection.Horizontal }).onAction((event: GestureEvent) => {
- if (event) {//手势返回
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = !this.isShowDrawer
- if(this.isShowDrawer)
- this.offsetX = 0
- })
- }
- }))
- }
- .showControlButton(false)
- .minContentWidth(0)
- .sideBarWidth(260)
- .autoHide(true)
- .showSideBar($$this.isShowDrawer)
- .onChange((value: boolean) => {
- this.isShowDrawer = value
- })
- }
- @Builder
- centerName() {
- Column() {
- Text(this.currentSong?.name)
- .fontSize(16)
- .textOverflow({ overflow: TextOverflow.MARQUEE }) //超长滚动
- .maxLines(1)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bolder);
- Row() {
- Text(this.currentSong?.artist)
- .margin({ top: 2 })
- .fontSize(13)
- .textAlign(TextAlign.Start)
- .maxLines(1)
- .fontWeight(FontWeight.Bold)
- .textOverflow({ overflow: TextOverflow.MARQUEE }) //超长滚动
- .fontColor(Color.White)
- }
- .visibility(this.currentSong?.artist? Visibility.Visible:Visibility.None)
- }
- .alignItems(HorizontalAlign.Center)
- }
- setShowPlayTrue(){
- if (this.isShowPlay === true) {
- this.isShowPlay = false
- }
- this.getUIContext()?.animateTo({
- duration: 500,
- curve: Curve.Friction
- }, () => {
- this.isShowPlay = true;
- });
- this.getUIContext().getHostContext()!.eventHub.emit('showPlayerView');
- }
- @Builder
- PlayController() {
- Row() {
- this.playConLeft(!this.curDisplayIsHiCar)
- if(!this.curDisplayIsHiCar){
- this.playConRigth()
- }
- if(this.curDisplayIsHiCar){
- Column(){
- this.centerName()
- }
- .layoutWeight(1)
- .onClick(()=>{
- this.setShowPlayTrue()
- })
- }
- }
- .width('100%')
- .height(this.bottomBarHeight)
- .hitTestBehavior(HitTestMode.Transparent)
- .zIndex(2)
- .onTouch((event: TouchEvent) => {
- if (event.type === TouchType.Down) {
- this.pointLightOptions = {
- color: this.themeColor,
- intensity: 1,
- height: 60
- }
- } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
- this.pointLightOptions = undefined
- }
- })
- .visualEffect( deviceInfo.sdkApiVersion >= 20
- ? new hdsEffect.HdsEffectBuilder()
- .pointLight({
- options: this.pointLightOptions,
- illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER_CONTENT
- })
- .buildEffect()
- : undefined)
- .padding({
- left: 16,
- right: 16
- })
- }
- @Builder
- playConLeft(isLeft: boolean = true) {
- Row() {
- Image( StrUtil.isNotEmpty(this.currentSong?.pixelMapPath)?
- this.currentSong?.pixelMapPath:$r('app.media.alt'))
- .height(48)
- .objectFit(ImageFit.Contain)
- .alt( $r('app.media.alt'))
- .fillColor(this.themeColor)
- .borderRadius(8)
- .shadow({
- radius: 15,
- type: ShadowType.BLUR,
- color: 'on_primary'
- })
- .geometryTransition('cover', { follow: true }) // 绑定标识符
- if(!this.curDisplayIsHiCar){
- Column() {
- Text(this.currentSong?.name)
- .fontSize(16)
- .textOverflow({ overflow: TextOverflow.MARQUEE }) //超长滚动
- .maxLines(1)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bolder);
- Row() {
- Text(this.currentSong?.artist)
- .margin({ top: 2 })
- .fontSize(13)
- .textAlign(TextAlign.Start)
- .maxLines(1)
- .fontWeight(FontWeight.Bold)
- .textOverflow({ overflow: TextOverflow.MARQUEE }) //超长滚动
- .fontColor(Color.White)
- }
- .visibility(this.currentSong?.artist? Visibility.Visible:Visibility.None)
- }
- .padding({left:8})
- .alignItems(isLeft?HorizontalAlign.Start:HorizontalAlign.End)
- .margin({ right: isLeft?22:10 })
- }else{
- this.playConRigth()
- }
- }
- .padding({ right: 18 })
- .layoutWeight(1)
- .alignItems(VerticalAlign.Center)
- .justifyContent(FlexAlign.Start)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.8 })
- .onClick(() => {
- this.setShowPlayTrue()
- })
- }
- @Builder
- playConRigth() {
- Row() {
- SymbolGlyph($r('sys.symbol.backward_end_fill'))
- .fontSize(28)
- .fontColor([Color.White])
- .alignSelf(ItemAlign.Center)
- .visibility(this.isShowPrecious? Visibility.Visible:Visibility.None)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- .margin({ left: 8, right: 14 })
- .displayPriority(2)
- .onClick(() => {
- this.getUIContext().getHostContext()!.eventHub.emit('playPrevious');
- })
- //播放进度条
- Stack() {
- Progress({
- value: Math.floor(this.progressValue),
- type: ProgressType.Ring,
- })
- .color(this.themeColor)// 进度条前景色为灰色
- .height(38)
- .aspectRatio(CommonConstants.ASPECT_RATIO)
- Image(this.CONTROL_PlayStatus === PlayStatus.PLAY ? $r('app.media.hm_pause') : $r('app.media.hm_play2'))
- .height(36)
- .width(36)
- .displayPriority(3)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.5 })
- .fillColor(Color.White)
- .onClick(() => {
- this.getUIContext().getHostContext()!.eventHub.emit('playOrPause');
- })
- }
- SymbolGlyph($r('sys.symbol.forward_end_fill'))
- .fontSize(28)
- .fontColor([Color.White])
- .alignSelf(ItemAlign.Center)
- .margin({
- right: 14,
- left: 14
- })
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- .displayPriority(2)
- .onClick(() => {
- this.getUIContext().getHostContext()!.eventHub.emit('playNext');
- })
- Image($r('app.media.hm_playlist'))
- .height(26)
- .width(26)
- .displayPriority(1)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- .fillColor(Color.White)
- .onClick(() => {
- this.getUIContext().getHostContext()!.eventHub.emit('openPlayList');
- })
- }
- .margin({left:this.curDisplayIsHiCar?20:5})
- .justifyContent(this.curDisplayIsHiCar?FlexAlign.Start:FlexAlign.End)
- }
- //是不是hicar的屏幕分辨率
- isHiCar() {
- return this.curDisplayIsHiCar;
- }
- //是不是正常的手机竖屏
- isPhonePortrait() {
- LogUtil.info('twocold this.currentHeightBreakpoint = '+this.currentHeightBreakpoint)
- LogUtil.info('twocold this.currentWidthBreakpoint = '+this.currentWidthBreakpoint)
- if(DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_PHONE
- &&this.currentHeightBreakpoint == HeightBreakpoint.HEIGHT_LG
- &&this.currentWidthBreakpoint==WidthBreakpoint.WIDTH_SM){//如果是手机横屏,返回false
- return true
- }
- return false
- }
- /**
- * 判断是否横屏
- * @returns
- */
- isBigScreen() {
- if (this.currentWidthBreakpoint == WidthBreakpoint.WIDTH_LG) {
- return true
- }
- if (DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_PHONE
- && this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM
- && this.currentHeightBreakpoint == HeightBreakpoint.HEIGHT_LG) {
- return false
- } else {
- return true
- }
- return false
- }
- @Builder
- getLeftView() {
- Column() {
- Column() {
- this.getDrawerView()
- }
- .width('100%')
- .height('100%')
- .onClick((event: ClickEvent) => {
- // 点击抽屉内部不关闭,通过返回值阻止事件传播
- return true
- })
- }
- // .width(this.currentBreakpoint !== BreakpointTypeEnum.SM?'36%':'70%')
- .height('100%')
- .borderRadius({
- topLeft: 0,
- topRight: 20,
- bottomLeft: 0,
- bottomRight: 20
- })
- // .backgroundColor($r('app.color.silvery'))
- // .backgroundColor($r('app.color.index_background'))
- .backgroundColor($r('app.color.user_center_card_background'))
- .alignItems(HorizontalAlign.Start)
- .translate({ x: this.offsetX, y: 0, z: 0 })
- .transition({ type: TransitionType.Insert, translate: { x: -DisplayUtil.getWidth(), y: 0 } })
- .transition({ type: TransitionType.Delete, translate: { x: -DisplayUtil.getWidth(), y: 0 } })
- .gesture(
- PanGesture()
- .onActionUpdate((event: GestureEvent) => {
- // 手势滑动更新抽屉偏移
- if (event.offsetX < 0) {
- this.offsetX = event.offsetX;
- }
- })
- .onActionEnd(() => {
- // 手势结束判断是否关闭抽屉
- if (this.offsetX < -DisplayUtil.getWidth() / 15) {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- } else {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = true
- this.offsetX = 0
- })
- }
- })
- )
- }
- @State isLogin: boolean = false;
- @State userAvatar: Resource = $r('app.media.icon_person2');
- @State userAvatarUrl: string = '';
- @State isVip: boolean = false;
- @State userName: string = '未登录用户';
- @State userId: number = 0;
- @State hasActiveSubscription: boolean = false;
- @State subscriptionName: string = '';
- @State subscriptionEndDate: string = '';
- // 用户信息卡片
- @Builder
- buildUserInfoCard() {
- Column() {
- this.userInfoView()
- Column({ space: 20 }) {
- SegmentButton({ options: this.tabOptions, selectedIndexes: $tabSelectedIndexes })
- }
- .padding({ bottom:10 })
- .width('90%')
- }
- }
- @Builder
- userInfoView() {
- Stack({ alignContent: Alignment.BottomEnd }) {
- Row() {
- Stack({ alignContent: Alignment.BottomEnd }){
- Image(this.userAvatarUrl && this.userAvatarUrl.length > 0 ? this.userAvatarUrl : this.userAvatar)
- .width(55)
- .height(55)
- .margin({ left: 12 })
- .borderRadius('50%')
- .clip(true)
- // .fillColor(this.themeColor)
- // .backgroundColor(this.isDarkMode ? Color.Black : Color.White)
- Column() {
- Text('VIP')
- .fontSize(9)
- .padding(2)
- .textAlign(TextAlign.Center)
- .fontWeight(FontWeight.Bolder)
- .fontColor(Color.White)
- }
- .width(28)
- .height(16)
- .visibility(Utility.isNoble()?Visibility.Visible:Visibility.None)
- .borderRadius(15)
- .backgroundColor(this.themeColor)
- }
- Column() {
- Row() {
- Text(this.isLogin ? this.userName : '未登录用户')
- .fontSize(14)
- // .fontWeight(FontWeight.Bold)
- // .fontColor(this.isDarkMode ? Color.White : Color.Black)
- .textAlign(TextAlign.Start)
- .maxLines(1)
- .width(110)
- .margin({ right: 12 })
- }
- .justifyContent(FlexAlign.Start)
- .margin({ top: 2 })
- if (this.isLogin) {
- if (this.hasActiveSubscription) {
- // Text(this.subscriptionName)
- // .fontSize(13)
- // .fontColor(themeColorWithAlpha(this.themeColor, 0.8, false))
- // .textAlign(TextAlign.Start)
- // .padding({top:5})
- this.TimeTextBuilder()
- } else {
- Text('普通用户')
- .fontSize(13)
- .fontColor(this.isDarkMode ? Color.White : Color.Grey)
- .textAlign(TextAlign.Start)
- .padding({top:5})
- this.TimeTextBuilder()
- }
- } else {
- this.TimeTextBuilder()
- }
- }
- .alignItems(HorizontalAlign.Start)
- .width(80)
- .margin({ left: 10 })
- }
- .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
- .onClick(() => {
- // if (!this.isLogin) {
- this.mType = 1
- if (!this.isBigScreen()) {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- // }
- }
- })
- .width('100%')
- .padding(10)
- PointLightDefaultButton({
- isPx: false,
- isSysBol: true,
- pointColor: $r('app.color.text_color'),
- imageResource: $r('sys.symbol.gearshape'),
- builderHeight: 32,
- builderWidth: 32,
- buttonScale: 1,
- canShadow: false,
- })
- .margin({ right: 2, bottom: 2 })
- .onClick(() => {
- this.mType = 4
- if (!this.isBigScreen()) {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- }
- })
- }
- .backgroundColor($r('app.color.user_center_card_background'))
- .borderRadius(24)
- .width('86%')
- .padding(8)
- .margin({ left: 10, right: 10, top: this.topRectHeight + 10,bottom:10 })
- .shadow({
- radius: 8,
- color: 0x11000000,
- offsetX: 0,
- offsetY: 2
- })
- }
- @Builder
- TimeTextBuilder() {
- Text(Utility.getTimePeriod())
- .fontSize(13)
- .margin({ top: 5 })
- .fontColor($r('app.color.text_color'))
- .align(Alignment.Start)
- }
- @State ratioL: number = 1;
- @State isRefreshing: boolean = false;
- @State maxRefreshingHeight: number = 100.0;
- private contentNode?: ComponentContent<Object> = undefined;
- /**
- * 动态生成抽屉菜单内容
- * 根据 isShowSponsorship 展示不同菜单项
- */
- @Builder
- getDrawerView() {
- Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
- List({ space: 0, scroller: this.scroller }) {
- ListItemGroup({ header: this.buildUserInfoCard() }) {
- if(this.tabSelectedIndexes[0]==0){//分类
- this.buildTabCate()
- }else if(this.tabSelectedIndexes[0]==1){//歌单
- this.buildPlaylistTab()
- }else if(this.tabSelectedIndexes[0]==2){//网盘
- this.buildCloudStorageTab()
- }
- }
- }
- .scrollBar(BarState.Off)
- .width('86%')
- .borderRadius(20)
- .margin({
- bottom: 20,
- left: 10,
- right: 10,
- top: 10
- })
- .alignListItem(ListItemAlign.Center)
- .layoutWeight(1)
- .backgroundColor($r('app.color.left_draw_bg'))
- .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
- }
- .pullDownRatio(this.ratioL)
- .pullToRefresh(true)
- .refreshOffset(0)
- .onOffsetChange((offset: number) => {
- // 越接近最大距离,下拉跟手系数越小。
- this.ratioL = 1 - Math.pow((offset / this.maxRefreshingHeight), 3);
- })
- .onStateChange((refreshStatus: RefreshStatus) => {
- console.info('onecold Refresh onStatueChange state is ' + refreshStatus);
- })
- .onRefreshing(async () => {
- if(this.tabSelectedIndexes[0]==0){//分类
- this.isRefreshing = false
- }else if(this.tabSelectedIndexes[0]==1){//歌单
- this.loadPlaylistList()
- }else if(this.tabSelectedIndexes[0]==2){//网盘
- this.loadWebDavAccounts()
- }
- })
- }
- @Builder
- buildTabCate() {
- ForEach(mainViewModel.getDrawerData(), (item: ItemData, index: number) => {
- ListItem() {
- Button({ type: ButtonType.Capsule, stateEffect: true }) {
- Row() {
- // 菜单图标
- if (typeof item.img === 'object' && item.img !== null && (item.img as sysResource).type === 'symbol') {
- SymbolGlyph((item.img as sysResource).value as Resource)// .size({ width: 22, height: 22 })
- .fontSize(22)
- .fontColor([this.themeColor])
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 15 })
- } else {
- Image(item.img as Resource)
- .height(22)
- .alignSelf(ItemAlign.Center)
- .fillColor(this.themeColor)
- .margin({ left: 15 })
- }
- // 菜单标题
- Text(item.title)
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(this.isTextSelected(index) ? this.themeColor : $r('app.color.index_tab_font_color'))
- .fontWeight(480)
- Blank()
- // 右侧箭头
- Image($r('app.media.arrow_right'))
- .width(22)
- .height(22)
- .margin({ left: 20, right: 0 })
- .align(Alignment.Center)
- }
- .width('100%')
- .height(55)
- }
- .backgroundColor(Color.Transparent)
- .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
- .onClick(async () => {
- // 根据 item.id 跳转或切换功能
- switch (item.id) {
- case MainViewModel.MENU_MUSIC:
- this.mType = 0
- this.modeType = 0
- this.currentSongListID = ''
- this.doShowDrawer()
- break
- case MainViewModel.MENU_FIND:
- this.mType = 8
- this.modeType = 0
- this.currentSongListID = ''
- this.doShowDrawer()
- break
- case MainViewModel.MENU_FILE_SCAN:
- this.mType = 2
- this.doShowDrawer()
- break
- case MainViewModel.MENU_CHARTS:
- this.mType = 3
- this.modeType = 0
- this.doShowDrawer()
- break
- case MainViewModel.MENU_MIEDIA_KU:
- this.modeType = 1
- this.mType = 0
- this.currentSongListID = ''
- this.doShowDrawer()
- break
- case MainViewModel.MENU_MIEDIA_ARTIST:
- this.modeType = 2
- this.mType = 0
- this.currentSongListID = ''
- this.doShowDrawer()
- break
- case MainViewModel.MENU_MIEDIA_ALBUM:
- this.modeType = 3
- this.mType = 0
- this.currentSongListID = ''
- this.doShowDrawer()
- break
- case MainViewModel.MENU_SETTING:
- this.mType = 4
- this.doShowDrawer()
- break
- case MainViewModel.MENU_VIP:
- router.pushUrl({
- url: 'pages/VipPage'
- }, router.RouterMode.Single);
- break
- case MainViewModel.MENU_USER:
- this.mType = 1
- this.doShowDrawer()
- break
- case MainViewModel.MENU_NET_CONNECT:
- this.mType = 1
- this.doShowDrawer()
- break
- case MainViewModel.MENU_SIMI:
- router.pushUrl({
- url: 'pages/VerifyPage'
- });
- break
- case MainViewModel.MENU_DUTY:
- router.pushUrl({
- url: 'pages/WebIndex',
- params: { titleName: '用户协议', webUrl: CommonConstants.NEW_DUTY }
- });
- break
- case MainViewModel.MENU_HAOPING:
- Utility.gotoMarket(getContext(this) as common.UIAbilityContext, this.bundleName)
- break
- case MainViewModel.MENU_ABOUT:
- this.mType = 5
- this.doShowDrawer()
- break
- case MainViewModel.MENU_UPDATE:
- AlertDialog.show({
- title: '版本更新',
- message: '当前版本为最新版本:' + this.versionName,
- autoCancel: true,
- alignment: DialogAlignment.Center,
- offset: { dx: 0, dy: -20 }, //在Y轴方向上的编译量
- confirm: {
- value: '确定',
- fontColor: Color.White,
- backgroundColor: $r('app.color.title_bar_bg'),
- action: () => {
- }
- }
- })
- break
- case MainViewModel.MENU_YSZC:
- router.pushUrl({
- url: 'pages/WebIndex',
- params: { titleName: '隐私政策', webUrl: CommonConstants.NEW_YS_HW }
- });
- break
- case MainViewModel.MENU_SHARE:
- gotoShare(this.context,this.appName,this.bundleName)
- break
- }
- })
- }
- .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
- .animation({ duration: 600, curve: Curve.Ease, delay: 60 * index }))
- .width('90%')
- .height(55)
- })
- }
- isTextSelected(index:number):boolean{
- if(this.mType == 0){
- return this.modeType == index
- }
- if (this.mType == 8) {
- return index == 4
- }
- if (this.mType == 2) {
- return index == 5
- }
- if (this.mType == 3) {
- return index == 6
- }
- if (this.mType == 5) {
- return index == 7
- }
- return false
- }
- doShowDrawer(){
- if (!this.isBigScreen()) {
- this.getUIContext()?.animateTo({ duration: 555 }, () => {
- this.isShowDrawer = false
- })
- }
- }
- @Builder
- updateSheet() {
- Scroll() {
- Column() {
- OnlineUpdateLog()
- }
- }
- .width('100%')
- .height('100%')
- }
- // /**
- // * ================== 穿山甲广告相关 ==================
- // */
- // /** Banner广告对象 */
- // private declare bannerAd: CSJNativeExpressAd;
- // /** 广告加载状态 */
- // @State private status: string = "未加载"
- // /** 是否展示广告 */
- // @State private isShowAd: boolean = false
- // /** 广告位配置信息 */
- // private declare mAdSlot: AdSlot;
- // /** 服务端bidding广告内容(可选) */
- // private mBiddingAdm = ''
- // /** 广告加载监听器 */
- // private expressLoadAdListener: NativeExpressAdListener = {
- // /**
- // * 广告加载失败回调
- // */
- // onError: (code: number, message: string) => {
- // console.error("加载广告失败,code=" + code + ",message=" + message);
- // this.status = "加载广告失败,code=" + code + ",message=" + message;
- // },
- // /**
- // * 广告加载成功回调
- // * @param ads 返回的广告列表
- // */
- // onNativeExpressAdLoad: (ads: ArrayList<CSJNativeExpressAd>) => {
- // console.log("BannerExpressAdPage==onNativeExpressAdLoad......success");
- // if (ads && ads.length > 0) {
- // ads.forEach((ad: CSJNativeExpressAd, idx: number) => {
- // // 设置广告交互监听
- // ad.setExpressInteractionListener({
- // /** 广告点击回调 */
- // onAdClicked: (type: number) => {
- // console.log("BannerExpressAdPage==onAdClicked......");
- // },
- // /** 广告展示回调 */
- // onAdShow: (type: number) => {
- // console.log("BannerExpressAdPage==onAdShow......");
- // },
- // /** 模板渲染失败回调 */
- // onRenderFail: (code: number, msg: string) => {
- // console.log("BannerExpressAdPage==onRenderFail...code=" + code + ",msg=" + msg);
- // },
- // /** 模板渲染成功回调 */
- // onRenderSuccess: (width: number, height: number) => {
- // console.log("BannerExpressAdPage==onRenderSuccess......width=" + width + ",height=" + height);
- // this.bannerAd = ad;
- // this.status = "广告加载完成待展示";
- // this.showBannerAd()
- // }
- // })
- // // 设置广告轮播时间
- // ad.setSlideIntervalTime(30 * 1000);//设置轮播时间长
- // this.setDislikeCallback(ad); //设置dislike
- // ad.render(this.getUIContext()) // 开始渲染广告
- // this.status = "广告加载中...";
- // });
- // }
- // }
- // }
- //
- // /**
- // * 设置广告 dislike 回调
- // * @param ad 广告对象
- // */
- // private setDislikeCallback(ad: CSJNativeExpressAd) {
- // ad.setDislikeCallback({
- // /** dislike 弹窗显示 */
- // onShow: () => {
- // console.log("BannerExpressAdPage==dislike......show");
- // },
- // /** 选择 dislike 选项 */
- // onSelected: (position: number, value: string, enforceRemove: boolean) => {
- // this.isShowAd = false;
- // console.log("BannerExpressAdPage==dislike......onSelected:position=" + position + ",value:" + value + ",enforce=" + enforceRemove);
- // },
- // /** 点击取消 dislike */
- // onCancel: () => {
- // console.log("BannerExpressAdPage==dislike......onCancel");
- // }
- // })
- // }
- //
- // /**
- // * 加载Banner广告
- // * @param rit 广告位ID
- // */
- // loadBannerAd(rit: string) {
- // // 仅在满足条件时加载广告
- // if(!Utility.isNoble()){
- // return
- // }
- // if(!Utility.isPassInstallTime(2)){
- // return
- // }
- // this.isShowAd = false;
- // let adCreator:CSJAdCreator = CSJAdSdk.getAdCreator()
- // this.mAdSlot = new AdSlotBuilder()
- // .setCodeId(rit)
- // .setAcceptSize(CSJUtil.BANNER_WIGTH, CSJUtil.BANNER_HEIGHT)
- // .setAdCount(1)
- // .setBidAdm(this.mBiddingAdm)
- // .build()
- // PrintBiddingTokenUtils.printBiddingToken(this.mAdSlot, adCreator);
- // adCreator.loadBannerAd(this.mAdSlot, this.expressLoadAdListener)
- // this.status = "广告加载中..."
- // }
- @StorageProp('currentHeightBreakpoint') currentHeightBreakpoint: HeightBreakpoint | undefined =
- HeightBreakpoint.HEIGHT_LG;
- @StorageProp('currentWidthBreakpoint') currentWidthBreakpoint: WidthBreakpoint | undefined = WidthBreakpoint.WIDTH_SM;
- @StorageProp('topRectHeight') topRectHeight: number = px2vp(AppUtil.getStatusBarHeight());
- //是否是Pura X外屏,或者小屏幕
- isPuraWP() {
- return this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM
- && this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD
- }
- //是否是Pura X外屏,或者小屏幕或者手机横屏
- isCoverOpacity() {
- if (this.isPuraWP()) {
- return true
- }
- if (this.isPhoneLan()) {
- return true
- }
- if (deviceInfo.marketName.includes('Pura X')
- && this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_SM) {
- return true
- }
- return false
- }
- //是不是手机横屏
- isPhoneLan() {
- if (DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_PHONE
- && this.currentBreakpoint !== BreakpointTypeEnum.SM) {
- if (DisplayUtil.getFoldStatus() === 0) {
- return true
- }
- }
- return false
- }
- isLoginChange() {
- this.refreshUserInfoState();
- }
- /**
- * 构建歌单tab内容
- */
- @Builder
- buildPlaylistTab() {
- // 创建歌单按钮
- ListItem() {
- Button({ type: ButtonType.Capsule, stateEffect: true }) {
- Row() {
- SymbolGlyph($r('sys.symbol.plus_circle'))
- .fontSize(22)
- .fontColor([this.themeColor])
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
-
- Text('创建歌单')
- .margin({ left: 10, right: 20 })
- .fontSize(14)
- .fontColor($r('app.color.index_tab_font_color'))
- .fontWeight(480)
-
- Blank()
-
- Image($r('app.media.arrow_right'))
- .width(22)
- .height(22)
- .margin({ left: 20, right: 0 })
- .align(Alignment.Center)
- }
- .width('100%')
- .height(55)
- }
- .backgroundColor(Color.Transparent)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- .onClick(() => {
- this.showCreatePlaylistDialog()
- })
- }
-
- // 歌单列表
- ForEach(this.playlistList, (playlist: Playlist,index:number) => {
- ListItem() {
- Button({ type: ButtonType.Capsule, stateEffect: true }) {
- Row() {
- Image(playlist.coverPath || $r('app.media.hm_playlist'))
- .width(22)
- .height(22)
- .margin({ left: 25 })
- .borderRadius(4)
- .fillColor(this.themeColor)
- .clip(true)
-
- Column() {
- Text(playlist.name)
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor($r('app.color.index_tab_font_color'))
- .fontWeight(480)
- .maxLines(1)
- .textOverflow({ overflow: TextOverflow.Ellipsis })
-
- Text(`${playlist.songCount}首`)
- .margin({ left: 10, right: 20 })
- .fontSize(12)
- .fontColor($r('app.color.index_tab_font_color'))
- .opacity(0.7)
- }
- .alignItems(HorizontalAlign.Start)
-
- Blank()
-
- Image($r('app.media.arrow_right'))
- .width(22)
- .height(22)
- .margin({ left: 20, right: 0 })
- .align(Alignment.Center)
- }
- .width('100%')
- .height(55)
- }
- .backgroundColor(Color.Transparent)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- .onClick(async () => {
- let targetPlaylist: Playlist = playlist;
- try {
- if (this.playlistTable) {
- const latestPlaylist = await this.playlistTable.queryPlaylistById(playlist.id);
- if (latestPlaylist) {
- targetPlaylist = latestPlaylist;
- const targetIndex = this.playlistList.findIndex((item: Playlist) => item.id === latestPlaylist.id);
- if (targetIndex >= 0) {
- this.playlistList[targetIndex] = latestPlaylist;
- this.playlistList = [...this.playlistList];
- }
- }
- }
- } catch (error) {
- LogUtil.warn('heanup NewIndex', `点击歌单时刷新最新数据失败: ${(error as Error).message}`);
- }
- if(targetPlaylist.songCount==0){
- this.openPlaylist(targetPlaylist)
- }else{
- this.doShowDrawer();
- this.mType = 0
- this.modeType = 4
- this.currentSongListName = targetPlaylist.name;
- this.currentSongListID = targetPlaylist.id;
- }
- })
- .bindContextMenu(this.MenuBuilder(playlist), ResponseType.LongPress,
- {
- preview: MenuPreviewMode.IMAGE,
- previewAnimationOptions: { scale: [0.8, 1.0] },
- })
- .bindContextMenu(this.MenuBuilder(playlist), ResponseType.RightClick,
- {
- preview: MenuPreviewMode.IMAGE,
- previewAnimationOptions: { scale: [0.8, 1.0] },
- })
- }
- .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
- .animation({ duration: 600, curve: Curve.Ease, delay: 60 * index }))
- })
- }
- /**
- * 构建网盘tab内容 - 从数据库获取所有网盘账户
- * 支持多种类型的网盘账户(目前支持WebDAV,将来可扩展其他类型)
- */
- @Builder
- buildCloudStorageTab() {
- // 当前只支持网盘账户,将来可以在这里添加其他类型的网盘账户
- // 例如:OneDrive, Google Drive, Dropbox等
- // 添加新账户按钮
- ListItem() {
- Button({ type: ButtonType.Capsule, stateEffect: true }) {
- Row() {
- SymbolGlyph($r('sys.symbol.plus_circle'))
- .fontSize(22)
- .fontColor([this.themeColor])
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
- Text(`添加${getRemoteDriveAccountLabel()}`)
- .margin({ left: 10, right: 20 })
- .fontSize(14)
- .fontColor($r('app.color.index_tab_font_color'))
- .fontWeight(480)
- Blank()
- Image($r('app.media.arrow_right'))
- .width(22)
- .height(22)
- .margin({ left: 20, right: 0 })
- .align(Alignment.Center)
- }
- .width('100%')
- .height(55)
- }
- .backgroundColor(Color.Transparent)
- .bindMenu(this.AddMenuBuilder)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
- }
- // 显示所有网盘账户
- ForEach(this.webDavAccounts, (account: WebDavAccount,index:number) => {
- ListItem() {
- Button({ type: ButtonType.Capsule, stateEffect: true }) {
- Row() {
- // 账户封面或默认图标
- Stack() {
- Image(account.coverPath?account.coverPath:getCloudDiskIcon(account.webType))
- .width(25)
- .height(25)
- .borderRadius(4)
- .objectFit(ImageFit.Cover)
- }
- .margin({ left: 20 })
- Column() {
- // 账户名称
- Text(account.name)
- .margin({ left: 8, right: 20 })
- .fontSize(15)
- .fontColor(this.selectedAccount==account?this.themeColor:$r('app.color.text_color'))
- .fontWeight(480)
- .maxLines(1)
- .textOverflow({ overflow: TextOverflow.Ellipsis })
- Row() {
- // 账户类型标签
- Text(getRemoteDriveDisplayLabel(account.webType))
- .fontSize(10)
- .fontColor(this.selectedAccount==account?this.themeColor:$r('app.color.index_tab_font_color'))
- .opacity(0.8)
- .padding({ left: 8, top: 2, bottom: 2 })
- .borderRadius(3)
- // 服务器地址
- Text(`@${account.isUseLocalHost ? account.localHost : account.host}:${account.port}`)
- .fontSize(12)
- .fontColor(this.selectedAccount==account?this.themeColor:$r('app.color.index_tab_font_color'))
- .opacity(0.7)
- .maxLines(1)
- .padding({ right: 8, top: 2, bottom: 2 })
- .textOverflow({ overflow: TextOverflow.Ellipsis })
- }
- }
- .alignItems(HorizontalAlign.Start)
- Blank()
- }
- .width('100%')
- .height(60)
- }
- .backgroundColor(Color.Transparent)
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.8 })
- .onClick(() => {
- console.info('heanup', '点击网盘账户:', account.name)
- this.selectWebDavAccount(account)
- })
- .bindContextMenu(this.MenuDavBuilder(account), ResponseType.LongPress,
- {
- preview: MenuPreviewMode.IMAGE,
- previewAnimationOptions: { scale: [0.8, 1.0] },
- })
- .bindContextMenu(this.MenuDavBuilder(account), ResponseType.RightClick,
- {
- preview: MenuPreviewMode.IMAGE,
- previewAnimationOptions: { scale: [0.8, 1.0] },
- })
- }
- .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
- .animation({ duration: 600, curve: Curve.Ease, delay: 60 * index }))
- })
- // 如果没有账户,显示提示信息
- if (this.webDavAccounts.length === 0) {
- ListItem() {
- Text(`暂无${getRemoteDriveAccountLabel()},点击上方按钮添加`)
- .fontSize(14)
- .fontColor($r('app.color.index_tab_font_color'))
- .opacity(0.6)
- .textAlign(TextAlign.Center)
- .width('100%')
- .padding(20)
- }
- }
- }
- @Builder
- AddMenuBuilder() {
- Menu() {
- MenuItem({
- startIcon: $r('app.media.webdav'),
- content: $r('app.string.webdav')
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false,undefined,RemoteDriveType.WebDav)
- })
- MenuItem({
- startIcon: $r('app.media.smb'),
- content: $r('app.string.smb')
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false,undefined,RemoteDriveType.Smb)
- })
- MenuItem({
- startIcon: $r('app.media.ftp'),
- content: $r('app.string.ftp')
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false,undefined,RemoteDriveType.Ftp)
- })
- MenuItem({
- startIcon: $r('app.media.navidrome'),
- content: $r('app.string.navidrome')
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false,undefined,RemoteDriveType.Navidrome)
- })
- MenuItem({
- startIcon: $r('app.media.jellyfin'),
- content: 'Jellyfin'
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.Jellyfin)
- })
- MenuItem({
- startIcon: $r('app.media.emby'),
- content: $r('app.string.emby')
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.Emby)
- })
- MenuItem({
- startIcon: $r('app.media.audio_Station'),
- content: 'AudioStation'
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.AudioStation)
- })
- MenuItem({
- startIcon: $r('app.media.plex'),
- content: 'Plex'
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.Plex)
- })
- MenuItem({
- startIcon: $r('app.media.daoliyu'),
- content: '道理鱼'
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.DaoLiYu)
- })
- MenuItem({
- startIcon: $r('app.media.baiduwp'),
- content: '百度网盘'
- })
- .onClick(async () => {
- this.showRemoteDriveAccountDialog(false, undefined, RemoteDriveType.Baidu)
- })
- }.attributeModifier(new MenuModifier())
- }
- @Builder
- MenuBuilder(playlist: Playlist) {
- Menu(){
- MenuItem({
- symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.square_and_pencil')),
- content: '编辑歌单'
- })
- .onClick(async() => {
- this.openPlaylist(playlist)
- })
- MenuItem({
- symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.trash')),
- content: '删除歌单'
- })
- .onClick(async() => {
- this.deletePlaylist(playlist)
- })
- }
- }
- @Builder
- MenuDavBuilder(account: WebDavAccount) {
- Menu(){
- MenuItem({
- symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.square_and_pencil')),
- content: '编辑'
- })
- .onClick(async() => {
- this.showRemoteDriveAccountDialog(true,account)
- })
- MenuItem({
- symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.arrow_up_to_line')),
- content: '置顶'
- })
- .onClick(async() => {
- try {
- await this.webdavManager.pinAccount(account)
- // 重新加载网盘账户列表以更新UI排序
- await this.loadWebDavAccounts()
- ToastUtil.showToast('置顶成功')
- LogUtil.info('heanup NewIndex', '网盘账户置顶成功:', account.name)
- this.logAccount('info', `网盘账户置顶成功: ${account.name}`)
- } catch (error) {
- LogUtil.error('heanup NewIndex', `置顶网盘账户失败: ${(error as Error).message}`)
- ToastUtil.showToast('置顶失败')
- this.logAccount('error', `置顶网盘账户失败: ${(error as Error).message}`)
- }
- })
- MenuItem({
- symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.trash')),
- content: '删除'
- })
- .onClick(async() => {
- this.deleteWebDavAccount(account)
- })
- }
- }
- /**
- * 删除网盘账户
- */
- async deleteWebDavAccount(account: WebDavAccount) {
- try {
- // 显示确认对话框
- this.getUIContext().showAlertDialog({
- title: '删除账户',
- message: `确定要删除webdav账户"${account.name}"吗?`,
- primaryButton: {
- value: '取消',
- action: () => {}
- },
- secondaryButton: {
- value: '删除',
- fontColor: Color.Red,
- action: async () => {
- try {
- await this.webdavManager.removeAccount(account)
- ToastUtil.showToast('网盘账户删除成功')
- // 重新加载网盘账户列表
- await this.loadWebDavAccounts()
- LogUtil.info('heanup NewIndex', '网盘账户删除成功:', account.name)
- this.logAccount('info', `网盘账户删除成功: ${account.name}`)
- } catch (error) {
- LogUtil.error('heanup NewIndex', `删除网盘账户失败: ${(error as Error).message}`)
- ToastUtil.showToast('删除失败')
- this.logAccount('error', `删除网盘账户失败: ${(error as Error).message}`)
- }
- }
- }
- })
- } catch (error) {
- LogUtil.error('heanup NewIndex', `删除网盘账户操作失败: ${(error as Error).message}`)
- ToastUtil.showToast('操作失败')
- this.logAccount('error', `删除网盘账户操作失败: ${(error as Error).message}`)
- }
- }
- /**
- * 删除歌单
- */
- async deletePlaylist(playlist: Playlist) {
- if (playlist&&this.playlistTable) {
- // 显示确认对话框
- AlertDialog.show({
- title: '删除歌单',
- message: `确定要删除歌单"${playlist.name}"吗?此操作不可撤销。`,
- primaryButton: {
- value: '取消',
- action: () => {}
- },
- secondaryButton: {
- value: '删除',
- fontColor: Color.Red,
- action: async () => {
- if (this.playlistTable) {
- const success = await this.playlistTable.deletePlaylist(playlist.id)
- if (success) {
- ToastUtil.showToast('歌单删除成功')
- // 发送刷新事件
- emitter.emit({ eventId: EventConstants.EVENT_PLAYLIST_REFRESH }, {})
- } else {
- ToastUtil.showToast('歌单删除失败')
- }
- }
- }
- }
- })
- }
- }
- /**
- * 显示创建歌单对话框
- */
- showCreatePlaylistDialog() {
- if (!this.playlistTable) {
- ToastUtil.showToast('歌单功能初始化中,请稍后再试')
- return
- }
- // 使用新的歌单对话框,支持自定义封面
- showCreatePlaylistDialog(
- async (name: string, description: string, coverPath?: string) => {
- // 创建歌单
- const success = await this.playlistTable!.createPlaylist(name, description, coverPath)
- if (success) {
- ToastUtil.showToast('歌单创建成功')
- // 刷新歌单列表
- await this.loadPlaylistList()
- // 发送歌单刷新事件
- emitter.emit({ eventId: EventConstants.EVENT_PLAYLIST_REFRESH }, {})
- } else {
- ToastUtil.showToast('歌单创建失败')
- }
- },
- () => {
- // 取消创建歌单
- }
- )
- }
- /**
- * 打开歌单详情
- */
- openPlaylist(playlist: Playlist) {
- try {
- // 跳转到歌单详情页面
- router.pushUrl({
- url: 'pages/PlaylistDetailPage',
- params: {
- playlist: playlist
- }
- }).catch((err: Error) => {
- console.error('跳转到歌单详情页面失败:', err.message);
- ToastUtil.showToast('打开歌单失败');
- });
- } catch (error) {
- console.error('打开歌单失败:', error);
- ToastUtil.showToast('打开歌单失败');
- }
- }
- /**
- * 初始化歌单数据库
- */
- async initPlaylistTable() {
- try {
- this.playlistTable = new PlaylistTable(this.context)
- console.info('onecold 歌单数据库初始化成功')
- // 等待数据库初始化完成后再加载数据
- setTimeout(async () => {
- await this.loadPlaylistList()
- }, 500) // 延迟500ms确保数据库初始化完成
- } catch (error) {
- console.error('初始化歌单数据库失败:', error)
- }
- }
- /**
- * 加载歌单列表
- */
- async loadPlaylistList() {
- try {
- LogUtil.info('heanup NewIndex', '开始加载歌单列表')
- if (this.playlistTable) {
- const playlists = await this.playlistTable.queryAllPlaylists()
- // 强制触发UI更新
- this.playlistList = playlists.slice()
- LogUtil.info('heanup NewIndex', `成功加载 ${playlists.length} 个歌单`)
- } else {
- LogUtil.warn('heanup NewIndex', '歌单表未初始化')
- }
- this.isRefreshing = false
- } catch (error) {
- LogUtil.error('heanup NewIndex', `加载歌单列表失败: ${(error as Error).message}`)
- this.isRefreshing = false
- }
- }
- /**
- * 初始化WebDAV管理器
- */
- private logAccount(level: 'info' | 'warn' | 'error', message: string) {
- const tag = 'AccountCenter';
- switch (level) {
- case 'info':
- void ServerLogUtil.info(tag, message);
- break;
- case 'warn':
- void ServerLogUtil.warn(tag, message);
- break;
- case 'error':
- void ServerLogUtil.error(tag, message);
- break;
- default:
- break;
- }
- }
- private logHiCar(level: 'info' | 'warn' | 'error', message: string) {
- const tag = 'HiCarEntry';
- switch (level) {
- case 'info':
- void ServerLogUtil.info(tag, message);
- break;
- case 'warn':
- void ServerLogUtil.warn(tag, message);
- break;
- case 'error':
- void ServerLogUtil.error(tag, message);
- break;
- default:
- break;
- }
- }
- async initWebDavManager() {
- try {
- // 设置WebDAV管理器的上下文
- this.webdavManager.setContext(this.context)
- // 创建网盘账户表
- await this.webdavManager.createWebDavTableInDB()
- // 订阅WebDAV管理器事件
- this.webdavManager.subscribe((event: string) => {
- LogUtil.info('heanup NewIndex', '收到WebDAV事件:', event)
- this.logAccount('info', `收到WebDAV事件: ${event}`)
- if (event === 'QueryAccountsSucceed') {
- this.webDavAccounts = this.webdavManager.getAllWebDavAccounts().slice()
- }
- })
- // 首页EntryAblility去加载网盘账户了。所以这边不加载
- // await this.loadWebDavAccounts()
- LogUtil.info('heanup NewIndex', 'WebDAV管理器初始化成功')
- this.logAccount('info', 'WebDAV管理器初始化成功')
- } catch (error) {
- LogUtil.error('heanup NewIndex', `初始化WebDAV管理器失败: ${(error as Error).message}`)
- this.logAccount('error', `初始化WebDAV管理器失败: ${(error as Error).message}`)
- }
- }
- /**
- * 加载网盘账户列表
- */
- async loadWebDavAccounts() {
- try {
- LogUtil.info('heanup NewIndex', '开始加载网盘账户列表')
- this.logAccount('info', '开始加载网盘账户列表')
- await this.webdavManager.queryWebDavAccountsFromDB()
- // 强制触发UI更新
- this.webDavAccounts = this.webdavManager.getAllWebDavAccounts().slice()
- this.isRefreshing = false
- LogUtil.info('heanup NewIndex', `成功加载 ${this.webDavAccounts.length} 个网盘账户`)
- this.logAccount('info', `成功加载 ${this.webDavAccounts.length} 个网盘账户`)
- } catch (error) {
- this.isRefreshing = false
- LogUtil.error('heanup NewIndex', `加载网盘账户列表失败: ${(error as Error).message}`)
- this.logAccount('error', `加载网盘账户列表失败: ${(error as Error).message}`)
- }
- }
- /**
- * 选择网盘账户
- */
- selectWebDavAccount(account: WebDavAccount) {
- try {
- LogUtil.info('heanup NewIndex', '选择网盘账户:', account.name)
- this.logAccount('info', `选择网盘账户: ${account.name} (id=${account.id ?? 'unknown'}, webType=${account.webType})`)
- // 关键修复:立即设置 selectedAccount,确保后续使用的是正确的账户
- this.selectedAccount = account
- console.info('heanup selectWebDavAccount account.webType='+account.webType)
- // 如果账户未激活,先激活它
- if (!account.isActivate) {
- // 先将所有账户设为未激活
- this.webDavAccounts.forEach(acc => {
- acc.isActivate = false
- })
- // 立即激活选中的账户(不等待数据库)
- account.isActivate = true
- // 异步更新数据库中的激活状态(不阻塞UI)
- this.webdavManager.editAccount(account).then(() => {
- LogUtil.info('heanup NewIndex', '网盘账户激活成功:', account.name)
- this.logAccount('info', `网盘账户激活成功: ${account.name}`)
- }).catch((error: Error) => {
- LogUtil.error('heanup NewIndex', `编辑网盘账户失败: ${error.message}`)
- // 不显示Toast,避免干扰用户
- this.logAccount('error', `编辑网盘账户失败: ${error.message}`)
- })
- }
- // 根据账户类型切换到对应页面
- if (account.webType === RemoteDriveType.Navidrome
- || account.webType === RemoteDriveType.Jellyfin
- || account.webType === RemoteDriveType.Emby
- || account.webType === RemoteDriveType.AudioStation
- || account.webType === RemoteDriveType.Plex
- || account.webType === RemoteDriveType.DaoLiYu) {
- this.mType = 7
- LogUtil.info('heanup NewIndex', `切换到 Navidrome/Jellyfin/Emby/AudioStation/Plex/道理鱼 页面,webType=${account.webType}`)
- } else {
- this.mType = 6
- LogUtil.info('heanup NewIndex', `切换到 WebDAV 页面,webType=${account.webType}`)
- }
- this.doShowDrawer()
- // 打印最终确认
- LogUtil.info('heanup NewIndex', `选择完成: selectedAccount=${this.selectedAccount.name}, webType=${this.selectedAccount.webType}, mType=${this.mType}`)
- } catch (error) {
- LogUtil.error('heanup NewIndex', `选择网盘账户失败: ${(error as Error).message}`)
- ToastUtil.showToast('选择账户失败')
- this.logAccount('error', `选择网盘账户失败: ${(error as Error).message}`)
- }
- }
- /**
- * 显示添加网盘账户对话框
- */
- @State addDavDialogId:number = 1
- showRemoteDriveAccountDialog(isEditMode?: boolean,account?: WebDavAccount,driveType?:number) {
- const node: FrameNode | null = this.getUIContext().getFrameNodeById("test_text") || null;
- this.getUIContext().getPromptAction().openCustomDialog({
- builder: () => {
- this.webDavAccountBuilder(isEditMode,account,driveType)
- },
- levelMode: LevelMode.EMBEDDED, // 启用页面级弹出框
- levelUniqueId: node?.getUniqueId(), // 设置页面级弹出框所在页面的任意节点ID
- immersiveMode: ImmersiveMode.EXTEND, // 设置页面级弹出框蒙层的显示模式
- }).then((dialogId: number) => {
- this.addDavDialogId = dialogId;
- })
- }
- @Builder
- webDavAccountBuilder(isEditMode?: boolean,account?: WebDavAccount,driveType?:number) {
- RemoteDriveAccountDialog({
- isEditMode: isEditMode,
- account: account,
- initialDriveType: driveType,
- onCancel: () => {
- // 取消添加
- this.getUIContext().getPromptAction().closeCustomDialog(this.addDavDialogId)
- },
- onConfirm: (account: WebDavAccount) => {
- if(this.webDavAccounts.length>=1&&!Utility.isNoble()&&!isEditMode){
- ToastUtil.showToast('普通用户只能添加一个网盘账户,请开通会员')
- return
- }
- this.getUIContext().getPromptAction().closeCustomDialog(this.addDavDialogId)
- if (isEditMode && account?.id) {
- // 编辑模式:更新现有账户
- this.webdavManager.editAccount(account).then(() => {
- ToastUtil.showToast('修改成功')
- // 重新加载网盘账户列表,观察着模式去更新了,所以这里不需要更新,先注释掉
- // this.loadWebDavAccounts()
- LogUtil.info('heanup NewIndex', '网盘账户修改成功:', account.name)
- this.logAccount('info', `网盘账户修改成功: ${account.name}`)
- }).catch((error: Error) => {
- LogUtil.error('heanup NewIndex', `修改网盘账户失败: ${error.message}`)
- ToastUtil.showToast('修改失败')
- this.logAccount('error', `修改网盘账户失败: ${error.message}`)
- })
- } else {
- // 添加模式:创建新账户
- this.webdavManager.insertAccount(
- account.name,
- account.host,
- account.localHost,
- account.isUseLocalHost,
- account.port,
- account.filepath,
- account.lyricFilePath,
- account.uploadFilePath,
- account.imageFilePath,
- account.account,
- account.password,
- account.enableHttps,
- account.coverPath,
- account.webType,
- account.smbShare,
- account.smbDomain,
- account.navidromeBasePath,
- account.jellyfinBasePath,
- account.embyBasePath,
- account.ftpEncoding,
- account.baiduAccessToken,
- account.baiduRefreshToken,
- account.baiduTokenExpiresAt
- ).then(() => {
- ToastUtil.showToast('添加成功')
- // 重新加载网盘账户列表 观察着模式去更新了,所以这里不需要更新,先注释掉
- // this.loadWebDavAccounts()
- LogUtil.info('heanup NewIndex', '网盘账户添加成功:', account.name)
- this.logAccount('info', `网盘账户添加成功: ${account.name}`)
- }).catch((error: Error) => {
- LogUtil.error('heanup NewIndex', `添加网盘账户失败: ${error.message}`)
- ToastUtil.showToast('添加失败')
- this.logAccount('error', `添加网盘账户失败: ${error.message}`)
- })
- }
- }
- });
- }
- }
- // 1. 工具函数:将 #RRGGBB 字符串和透明度转为 'rgba(r,g,b,a)' 字符串,深色模式下可返回深色变体
- function themeColorWithAlpha(themeColor: string, alpha: number, isDarkMode: boolean = false): string {
- if (isDarkMode) {
- // 深色模式下返回更深的灰色或半透明黑色
- return `rgba(34,34,34,${alpha + 0.2 > 1 ? 1 : alpha + 0.2})`;
- }
- const color = themeColor.replace('#', '');
- const r = parseInt(color.substring(0, 2), 16);
- const g = parseInt(color.substring(2, 4), 16);
- const b = parseInt(color.substring(4, 6), 16);
- return `rgba(${r},${g},${b},${alpha})`;
- }
- // 定义接口
- interface HiCarAspectRatio {
- context: Context;
- playlistId: string;
- }
|