|
@@ -1,7 +1,6 @@
|
|
|
import TitleBar from './TitleBar'
|
|
import TitleBar from './TitleBar'
|
|
|
import { curves, display, PiPWindow, promptAction, router, SymbolGlyphModifier, window } from '@kit.ArkUI';
|
|
import { curves, display, PiPWindow, promptAction, router, SymbolGlyphModifier, window } from '@kit.ArkUI';
|
|
|
import { VideoItem } from '../viewmodel/VideoItem';
|
|
import { VideoItem } from '../viewmodel/VideoItem';
|
|
|
-import { stringForTime } from '../common/util/CommUtils';
|
|
|
|
|
import { Playlist } from '../viewmodel/Playlist';
|
|
import { Playlist } from '../viewmodel/Playlist';
|
|
|
import { LengthMetrics, SegmentButton,borderRadiuses, SegmentButtonOptions } from '@kit.ArkUI';
|
|
import { LengthMetrics, SegmentButton,borderRadiuses, SegmentButtonOptions } from '@kit.ArkUI';
|
|
|
import {
|
|
import {
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
import { imagePathToPixelMap } from '../common/util/CommUtils';
|
|
import { imagePathToPixelMap } from '../common/util/CommUtils';
|
|
|
import { unifiedDataChannel, uniformDataStruct, uniformTypeDescriptor } from '@kit.ArkData';
|
|
import { unifiedDataChannel, uniformDataStruct, uniformTypeDescriptor } from '@kit.ArkData';
|
|
|
import { CommonConstants } from '../common/constants/CommonConstants';
|
|
import { CommonConstants } from '../common/constants/CommonConstants';
|
|
|
|
|
+import { EventConstants } from '../common/constants/EventConstants';
|
|
|
import Logger from '../common/util/Logger';
|
|
import Logger from '../common/util/Logger';
|
|
|
import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|
import { photoAccessHelper } from '@kit.MediaLibraryKit';
|
|
|
import { BusinessError, emitter } from '@kit.BasicServicesKit';
|
|
import { BusinessError, emitter } from '@kit.BasicServicesKit';
|
|
@@ -94,9 +94,9 @@ import { showCreatePlaylistDialog } from '../dialog/PlaylistDialog';
|
|
|
const TAG = 'LocalMusic';
|
|
const TAG = 'LocalMusic';
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 简化的歌单播放事件数据
|
|
|
|
|
|
|
+ * 歌单播放事件数据
|
|
|
*/
|
|
*/
|
|
|
-interface SimplifiedPlaylistEventData {
|
|
|
|
|
|
|
+interface PlaylistEventData {
|
|
|
playlistId: string;
|
|
playlistId: string;
|
|
|
playlistName: string;
|
|
playlistName: string;
|
|
|
songCount: number;
|
|
songCount: number;
|
|
@@ -162,10 +162,9 @@ const ITEM_HEIGHT_BIG: number = 78; // 列表项大高度
|
|
|
@Preview
|
|
@Preview
|
|
|
@Component
|
|
@Component
|
|
|
export struct LocalMusic {
|
|
export struct LocalMusic {
|
|
|
- @State isRefreshing: boolean = false;
|
|
|
|
|
- @State maxRefreshingHeight: number = 100.0;
|
|
|
|
|
- private contentNode?: ComponentContent<Object> = undefined;
|
|
|
|
|
- @State ratioL: number = 1;
|
|
|
|
|
|
|
+ @Consume currentSongList: Array<VideoItem>//当前歌单
|
|
|
|
|
+ @Consume currentSongListName:string //当前歌单名称
|
|
|
|
|
+ @Consume @Watch('onIDChange') currentSongListID:string //当前歌单ID
|
|
|
@State mediaKuCount: number = 0;
|
|
@State mediaKuCount: number = 0;
|
|
|
@State albumCount: number = 0;
|
|
@State albumCount: number = 0;
|
|
|
@State artistCount: number = 0;
|
|
@State artistCount: number = 0;
|
|
@@ -194,7 +193,7 @@ export struct LocalMusic {
|
|
|
@Consume isHistory: boolean
|
|
@Consume isHistory: boolean
|
|
|
static readonly HISTORY_MUSIC: string = 'music_historyList';
|
|
static readonly HISTORY_MUSIC: string = 'music_historyList';
|
|
|
private table: MediaTable = new MediaTable(getContext(this))
|
|
private table: MediaTable = new MediaTable(getContext(this))
|
|
|
- private playlistTable: PlaylistTable = new PlaylistTable(getContext(this))
|
|
|
|
|
|
|
+ private playlistTable: PlaylistTable | null = null
|
|
|
@State allPlaylists: Playlist[] = []
|
|
@State allPlaylists: Playlist[] = []
|
|
|
@State isZero: boolean = false
|
|
@State isZero: boolean = false
|
|
|
@State fileList: Array<string> = []
|
|
@State fileList: Array<string> = []
|
|
@@ -296,6 +295,17 @@ export struct LocalMusic {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //歌单id发生变化的时候回调
|
|
|
|
|
+ onIDChange(){
|
|
|
|
|
+ if(this.modeType==4){
|
|
|
|
|
+ this.titleBarModel.setLeftIconMainNoAnimate($r('app.media.menu'))
|
|
|
|
|
+ this.updateListData(this.currentSongList, true)
|
|
|
|
|
+ this.titleBarModel.setTitleName(this.currentSongListName)
|
|
|
|
|
+ this.isShowTitleBar = false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
onModeChange() {
|
|
onModeChange() {
|
|
|
this.isFavMusic = false
|
|
this.isFavMusic = false
|
|
|
if (this.modeType === 2 || this.modeType === 3) {
|
|
if (this.modeType === 2 || this.modeType === 3) {
|
|
@@ -304,6 +314,7 @@ export struct LocalMusic {
|
|
|
this.titleBarModel.setRightIcon(($r('app.media.add')))
|
|
this.titleBarModel.setRightIcon(($r('app.media.add')))
|
|
|
}
|
|
}
|
|
|
LogUtil.info('onecold onModeChange = ' + this.modeType)
|
|
LogUtil.info('onecold onModeChange = ' + this.modeType)
|
|
|
|
|
+ this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, true)
|
|
|
switch (this.modeType) {
|
|
switch (this.modeType) {
|
|
|
case 0:
|
|
case 0:
|
|
|
this.getSortedFiles(this.currentPath)
|
|
this.getSortedFiles(this.currentPath)
|
|
@@ -324,6 +335,12 @@ export struct LocalMusic {
|
|
|
this.updateListData(this.albumList)
|
|
this.updateListData(this.albumList)
|
|
|
this.titleBarModel.setTitleName(Utility.resourceToString(this.context, $r('app.string.album')))
|
|
this.titleBarModel.setTitleName(Utility.resourceToString(this.context, $r('app.string.album')))
|
|
|
break
|
|
break
|
|
|
|
|
+ case 4://歌单
|
|
|
|
|
+ this.titleBarModel.setLeftIconMainNoAnimate($r('app.media.menu'))
|
|
|
|
|
+ this.updateListData(this.currentSongList, true)
|
|
|
|
|
+ this.titleBarModel.setTitleName(this.currentSongListName)
|
|
|
|
|
+ this.isShowTitleBar = false
|
|
|
|
|
+ break
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -523,6 +540,9 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
// 组件生命周期
|
|
// 组件生命周期
|
|
|
aboutToAppear() {
|
|
aboutToAppear() {
|
|
|
|
|
+ // 初始化 PlaylistTable
|
|
|
|
|
+ this.playlistTable = new PlaylistTable(getContext(this))
|
|
|
|
|
+
|
|
|
this.sonTwoFingerType = PreferencesUtil.getNumberSync('sonTwoFingerType', 3);
|
|
this.sonTwoFingerType = PreferencesUtil.getNumberSync('sonTwoFingerType', 3);
|
|
|
this.columns = PreferencesUtil.getNumberSync('lastColumns', 2);
|
|
this.columns = PreferencesUtil.getNumberSync('lastColumns', 2);
|
|
|
if(PreferencesUtil.getBooleanSync('isFirstTiped',true)){
|
|
if(PreferencesUtil.getBooleanSync('isFirstTiped',true)){
|
|
@@ -546,7 +566,7 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- let eventMusic: emitter.InnerEvent = { eventId: 2 }
|
|
|
|
|
|
|
+ let eventMusic: emitter.InnerEvent = { eventId: EventConstants.EVENT_AUDIO_OPEN }
|
|
|
// 监听广播事件(打开其他应用处理)
|
|
// 监听广播事件(打开其他应用处理)
|
|
|
emitter.on(eventMusic, (eventData: emitter.EventData) => {
|
|
emitter.on(eventMusic, (eventData: emitter.EventData) => {
|
|
|
this.saveVideoDatas([eventData.data?.message], true)
|
|
this.saveVideoDatas([eventData.data?.message], true)
|
|
@@ -554,7 +574,7 @@ export struct LocalMusic {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
//侧滑广播接收时间
|
|
//侧滑广播接收时间
|
|
|
- let eventUpdateSwipeBack: emitter.InnerEvent = { eventId: 888 }
|
|
|
|
|
|
|
+ let eventUpdateSwipeBack: emitter.InnerEvent = { eventId: EventConstants.EVENT_SWIPE_BACK_UPDATE }
|
|
|
// 监听广播事件(打开其他应用处理)
|
|
// 监听广播事件(打开其他应用处理)
|
|
|
emitter.on(eventUpdateSwipeBack, (eventData: emitter.EventData) => {
|
|
emitter.on(eventUpdateSwipeBack, (eventData: emitter.EventData) => {
|
|
|
|
|
|
|
@@ -565,14 +585,14 @@ export struct LocalMusic {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
//ScanFilePage广播接收时间
|
|
//ScanFilePage广播接收时间
|
|
|
- let eventScanUpdate: emitter.InnerEvent = { eventId: 101 }
|
|
|
|
|
|
|
+ let eventScanUpdate: emitter.InnerEvent = { eventId: EventConstants.EVENT_SCAN_UPDATE }
|
|
|
// 监听ScanFilePage广播事件(更新数据库)
|
|
// 监听ScanFilePage广播事件(更新数据库)
|
|
|
emitter.on(eventScanUpdate, (eventData: emitter.EventData) => {
|
|
emitter.on(eventScanUpdate, (eventData: emitter.EventData) => {
|
|
|
this.doUpdateData()
|
|
this.doUpdateData()
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// 监听歌单播放请求事件
|
|
// 监听歌单播放请求事件
|
|
|
- let eventPlaylistPlay: emitter.InnerEvent = { eventId: 2002 }
|
|
|
|
|
|
|
+ let eventPlaylistPlay: emitter.InnerEvent = { eventId: EventConstants.EVENT_PLAYLIST_PLAY }
|
|
|
emitter.on(eventPlaylistPlay, (eventData: emitter.EventData) => {
|
|
emitter.on(eventPlaylistPlay, (eventData: emitter.EventData) => {
|
|
|
Logger.info('heanup eventPlaylistPlay received - full eventData: ' + JSON.stringify(eventData))
|
|
Logger.info('heanup eventPlaylistPlay received - full eventData: ' + JSON.stringify(eventData))
|
|
|
Logger.info('heanup eventPlaylistPlay received - eventData.data: ' + JSON.stringify(eventData.data))
|
|
Logger.info('heanup eventPlaylistPlay received - eventData.data: ' + JSON.stringify(eventData.data))
|
|
@@ -584,11 +604,11 @@ export struct LocalMusic {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 检查简化数据结构
|
|
|
|
|
|
|
+ // 检查歌单播放数据结构
|
|
|
if (data.playlistId && data.songFilePaths && data.startIndex !== undefined) {
|
|
if (data.playlistId && data.songFilePaths && data.startIndex !== undefined) {
|
|
|
- Logger.info('heanup eventPlaylistPlay: received simplified playlist data')
|
|
|
|
|
- // 手动构建简化数据对象以避免类型转换问题
|
|
|
|
|
- const simplifiedData: SimplifiedPlaylistEventData = {
|
|
|
|
|
|
|
+ Logger.info('heanup eventPlaylistPlay: 接收到歌单播放数据')
|
|
|
|
|
+ // 手动构建数据对象以避免类型转换问题
|
|
|
|
|
+ const playlistData: PlaylistEventData = {
|
|
|
playlistId: data.playlistId as string,
|
|
playlistId: data.playlistId as string,
|
|
|
playlistName: data.playlistName as string,
|
|
playlistName: data.playlistName as string,
|
|
|
songCount: data.songCount as number,
|
|
songCount: data.songCount as number,
|
|
@@ -596,26 +616,19 @@ export struct LocalMusic {
|
|
|
songFilePaths: data.songFilePaths as string[]
|
|
songFilePaths: data.songFilePaths as string[]
|
|
|
}
|
|
}
|
|
|
// 根据文件路径重新构建歌曲列表
|
|
// 根据文件路径重新构建歌曲列表
|
|
|
- this.handleSimplifiedPlaylistPlayRequest(
|
|
|
|
|
- simplifiedData.playlistId,
|
|
|
|
|
- simplifiedData.playlistName,
|
|
|
|
|
- simplifiedData.songFilePaths,
|
|
|
|
|
- simplifiedData.startIndex
|
|
|
|
|
|
|
+ this.handlePlaylistPlayRequest(
|
|
|
|
|
+ playlistData.playlistId,
|
|
|
|
|
+ playlistData.playlistName,
|
|
|
|
|
+ playlistData.songFilePaths,
|
|
|
|
|
+ playlistData.startIndex
|
|
|
)
|
|
)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 检查原始数据结构(向后兼容)
|
|
|
|
|
- if (data.playlist && data.songs && data.startIndex !== undefined) {
|
|
|
|
|
- Logger.info('heanup eventPlaylistPlay: received original playlist data')
|
|
|
|
|
- this.handlePlaylistPlayRequest(data.playlist as Playlist, data.songs as VideoItem[], data.startIndex as number)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Logger.error('heanup eventPlaylistPlay: invalid data structure received')
|
|
|
|
|
|
|
+ Logger.error('heanup eventPlaylistPlay: 接收到无效的数据结构')
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- let eventSetting: emitter.InnerEvent = { eventId: 333 }
|
|
|
|
|
|
|
+ let eventSetting: emitter.InnerEvent = { eventId: EventConstants.EVENT_SETTING_UPDATE }
|
|
|
// 监听广播事件(通用设置配置更新)
|
|
// 监听广播事件(通用设置配置更新)
|
|
|
emitter.on(eventSetting, (eventData: emitter.EventData) => {
|
|
emitter.on(eventSetting, (eventData: emitter.EventData) => {
|
|
|
this.doChangeSetting()
|
|
this.doChangeSetting()
|
|
@@ -765,7 +778,6 @@ export struct LocalMusic {
|
|
|
const context = getContext(this) as common.UIAbilityContext
|
|
const context = getContext(this) as common.UIAbilityContext
|
|
|
context.getApplicationContext().setColorMode(colorMode)
|
|
context.getApplicationContext().setColorMode(colorMode)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
initSetting() {
|
|
initSetting() {
|
|
|
this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4)
|
|
this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4)
|
|
|
this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false)
|
|
this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false)
|
|
@@ -896,7 +908,6 @@ export struct LocalMusic {
|
|
|
this.doUpdateData()
|
|
this.doUpdateData()
|
|
|
break;
|
|
break;
|
|
|
case 102: //查询媒体库列表
|
|
case 102: //查询媒体库列表
|
|
|
- this.isRefreshing = false
|
|
|
|
|
this.mediaKuList = e.data.data
|
|
this.mediaKuList = e.data.data
|
|
|
Logger.info('onecold 查询媒体库列表 this.mediaKuList length= ' + this.mediaKuList.length)
|
|
Logger.info('onecold 查询媒体库列表 this.mediaKuList length= ' + this.mediaKuList.length)
|
|
|
Utility.doSortListAscending(this.mediaKuList)
|
|
Utility.doSortListAscending(this.mediaKuList)
|
|
@@ -915,7 +926,6 @@ export struct LocalMusic {
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
case 103: //收到查询艺术家列表
|
|
case 103: //收到查询艺术家列表
|
|
|
- this.isRefreshing = false
|
|
|
|
|
this.artistMap = e.data.data1;
|
|
this.artistMap = e.data.data1;
|
|
|
this.artistList = e.data.data2;
|
|
this.artistList = e.data.data2;
|
|
|
PreferencesUtil.putSync('artistCount', this.artistList.length)
|
|
PreferencesUtil.putSync('artistCount', this.artistList.length)
|
|
@@ -928,12 +938,15 @@ export struct LocalMusic {
|
|
|
} else {
|
|
} else {
|
|
|
PreferencesUtil.putSync('artistList', JSON.stringify(this.artistList));
|
|
PreferencesUtil.putSync('artistList', JSON.stringify(this.artistList));
|
|
|
}
|
|
}
|
|
|
- const mapArray = Array.from(this.artistMap.entries());
|
|
|
|
|
- PreferencesUtil.putSync('artistMap', JSON.stringify(mapArray));
|
|
|
|
|
|
|
+ // 处理并缓存前60条艺术家数据
|
|
|
|
|
+ const sortedEntries = Array.from(this.artistMap.entries())
|
|
|
|
|
+ .sort((a, b) => b[1].length - a[1].length)
|
|
|
|
|
+ .slice(0, 60);
|
|
|
|
|
+
|
|
|
|
|
+ PreferencesUtil.putSync('artistMap', JSON.stringify(sortedEntries));
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case 104: //收到查询专辑列表
|
|
case 104: //收到查询专辑列表
|
|
|
- this.isRefreshing = false
|
|
|
|
|
this.albumMap = e.data.data1;
|
|
this.albumMap = e.data.data1;
|
|
|
|
|
|
|
|
this.albumList = e.data.data2
|
|
this.albumList = e.data.data2
|
|
@@ -952,7 +965,9 @@ export struct LocalMusic {
|
|
|
} else {
|
|
} else {
|
|
|
PreferencesUtil.putSync('albumList', JSON.stringify(this.albumList));
|
|
PreferencesUtil.putSync('albumList', JSON.stringify(this.albumList));
|
|
|
}
|
|
}
|
|
|
- const mapArrayAlbum = Array.from(this.albumMap.entries());
|
|
|
|
|
|
|
+ const mapArrayAlbum = Array.from(this.albumMap.entries())
|
|
|
|
|
+ .sort((a, b) => b[1].length - a[1].length)
|
|
|
|
|
+ .slice(0, 60);
|
|
|
PreferencesUtil.putSync('albumMap', JSON.stringify(mapArrayAlbum));
|
|
PreferencesUtil.putSync('albumMap', JSON.stringify(mapArrayAlbum));
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
@@ -1075,10 +1090,10 @@ export struct LocalMusic {
|
|
|
console.info('LifeCycleComponent aboutToDisappear');
|
|
console.info('LifeCycleComponent aboutToDisappear');
|
|
|
this.knockController?.immersiveDisableListening();
|
|
this.knockController?.immersiveDisableListening();
|
|
|
this.curIndex = 0
|
|
this.curIndex = 0
|
|
|
- emitter.off(2);
|
|
|
|
|
- emitter.off(101);
|
|
|
|
|
- emitter.off(888);
|
|
|
|
|
- emitter.off(333);
|
|
|
|
|
|
|
+ emitter.off(EventConstants.EVENT_AUDIO_OPEN);
|
|
|
|
|
+ emitter.off(EventConstants.EVENT_SCAN_UPDATE);
|
|
|
|
|
+ emitter.off(EventConstants.EVENT_SWIPE_BACK_UPDATE);
|
|
|
|
|
+ emitter.off(EventConstants.EVENT_SETTING_UPDATE);
|
|
|
this.mDestroyPage = true;
|
|
this.mDestroyPage = true;
|
|
|
this.mIjkMediaPlayer.setScreenOnWhilePlaying(false);
|
|
this.mIjkMediaPlayer.setScreenOnWhilePlaying(false);
|
|
|
if (this.CONTROL_PlayStatus != PlayStatus.INIT) {
|
|
if (this.CONTROL_PlayStatus != PlayStatus.INIT) {
|
|
@@ -1373,7 +1388,7 @@ export struct LocalMusic {
|
|
|
this.titleBarModel.setTitleName(Utility.resourceToString(this.context, $r('app.string.album')))
|
|
this.titleBarModel.setTitleName(Utility.resourceToString(this.context, $r('app.string.album')))
|
|
|
break
|
|
break
|
|
|
case 4: //同步数据
|
|
case 4: //同步数据
|
|
|
- this.asyncCurrentPathData()
|
|
|
|
|
|
|
+ // this.asyncCurrentPathData()
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1510,7 +1525,6 @@ export struct LocalMusic {
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
doSortType(index: number) {
|
|
doSortType(index: number) {
|
|
|
switch (index) {
|
|
switch (index) {
|
|
|
case 0:
|
|
case 0:
|
|
@@ -2149,7 +2163,6 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
build() {
|
|
build() {
|
|
|
|
|
|
|
|
Scroll() {
|
|
Scroll() {
|
|
@@ -2255,22 +2268,7 @@ export struct LocalMusic {
|
|
|
if(this.isGridMusic){
|
|
if(this.isGridMusic){
|
|
|
this.getGridView()
|
|
this.getGridView()
|
|
|
}else {
|
|
}else {
|
|
|
- Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
|
|
|
|
|
- this.getListView()
|
|
|
|
|
- }
|
|
|
|
|
- .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 () => {
|
|
|
|
|
- this.refreshCurrent()
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ this.getListView()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if (this.modeType == 0) {
|
|
if (this.modeType == 0) {
|
|
@@ -2649,10 +2647,10 @@ export struct LocalMusic {
|
|
|
*/
|
|
*/
|
|
|
async loadAllPlaylists() {
|
|
async loadAllPlaylists() {
|
|
|
try {
|
|
try {
|
|
|
- this.allPlaylists = await this.playlistTable.queryAllPlaylists()
|
|
|
|
|
- LogUtil.info('Loaded playlists: ' + this.allPlaylists.length)
|
|
|
|
|
|
|
+ this.allPlaylists = await this.playlistTable?.queryAllPlaylists()!
|
|
|
|
|
+ LogUtil.info('heanup Loaded playlists: ' + this.allPlaylists.length)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- LogUtil.error('Failed to load playlists: ' + error.message)
|
|
|
|
|
|
|
+ LogUtil.error('heaunp Failed to load playlists: ' + error.message)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2668,7 +2666,7 @@ export struct LocalMusic {
|
|
|
this.allPlaylists,
|
|
this.allPlaylists,
|
|
|
async (playlistId: string) => {
|
|
async (playlistId: string) => {
|
|
|
// 添加歌曲到歌单
|
|
// 添加歌曲到歌单
|
|
|
- const success = await this.playlistTable.addSongToPlaylist(playlistId, item.filePath)
|
|
|
|
|
|
|
+ const success = await this.playlistTable?.addSongToPlaylist(playlistId, item.filePath)
|
|
|
if (success) {
|
|
if (success) {
|
|
|
ToastUtil.showToast('已添加到歌单')
|
|
ToastUtil.showToast('已添加到歌单')
|
|
|
// 重新加载歌单列表
|
|
// 重新加载歌单列表
|
|
@@ -2684,7 +2682,7 @@ export struct LocalMusic {
|
|
|
// 创建新歌单
|
|
// 创建新歌单
|
|
|
showCreatePlaylistDialog(
|
|
showCreatePlaylistDialog(
|
|
|
async (name: string, description: string) => {
|
|
async (name: string, description: string) => {
|
|
|
- const success = await this.playlistTable.createPlaylist(name, description)
|
|
|
|
|
|
|
+ const success = await this.playlistTable?.createPlaylist(name, description)
|
|
|
if (success) {
|
|
if (success) {
|
|
|
ToastUtil.showToast('歌单创建成功')
|
|
ToastUtil.showToast('歌单创建成功')
|
|
|
// 重新加载歌单列表并打开添加对话框
|
|
// 重新加载歌单列表并打开添加对话框
|
|
@@ -2885,9 +2883,7 @@ export struct LocalMusic {
|
|
|
}
|
|
}
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
@State opacityItem: number = 1; // 控制透明度的状态变量
|
|
@State opacityItem: number = 1; // 控制透明度的状态变量
|
|
|
-
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
private MusicItem(item: VideoItem, index?: number) {
|
|
private MusicItem(item: VideoItem, index?: number) {
|
|
|
Button({ type: ButtonType.Normal, stateEffect: true }) {
|
|
Button({ type: ButtonType.Normal, stateEffect: true }) {
|
|
@@ -3085,7 +3081,7 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
private readonly tabs: string[] = ['文件夹', '媒体库', '艺术家', '专辑']
|
|
private readonly tabs: string[] = ['文件夹', '媒体库', '艺术家', '专辑']
|
|
|
@State tabOptions: SegmentButtonOptions = SegmentButtonOptions.tab({
|
|
@State tabOptions: SegmentButtonOptions = SegmentButtonOptions.tab({
|
|
|
- buttons: [{ text: '文件夹' }, { text: '媒体库' },{ text: '艺术家' },{ text: '专辑' }],
|
|
|
|
|
|
|
+ buttons: [{ text: '文件夹' }, { text: '媒体库' },{ text: '艺术家' }],
|
|
|
direction: Direction.Ltr,
|
|
direction: Direction.Ltr,
|
|
|
buttonPadding:{top:12,bottom:12},
|
|
buttonPadding:{top:12,bottom:12},
|
|
|
backgroundColor: Color.Transparent,
|
|
backgroundColor: Color.Transparent,
|
|
@@ -3368,20 +3364,6 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
return this.currentTitleCover
|
|
return this.currentTitleCover
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- refreshCurrent() {
|
|
|
|
|
- if(this.modeType==0){
|
|
|
|
|
- this.getHistoryList(false)
|
|
|
|
|
- this.asyncCurrentPathOnlyFile()
|
|
|
|
|
- }else if(this.modeType == 1){
|
|
|
|
|
- workerInstance.postMessage({ code: 2, data: this.context,data2:this.packName });
|
|
|
|
|
- }else if(this.modeType == 2){
|
|
|
|
|
- workerInstance.postMessage({ code: 3, data: this.context });
|
|
|
|
|
- }else if(this.modeType == 3){
|
|
|
|
|
- workerInstance.postMessage({ code: 4, data: this.context });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
listViewTitle() {
|
|
listViewTitle() {
|
|
|
Column() {
|
|
Column() {
|
|
@@ -3597,18 +3579,26 @@ export struct LocalMusic {
|
|
|
this.isSearchMode = true
|
|
this.isSearchMode = true
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // Image($r("app.media.refresh"))
|
|
|
|
|
- // .fillColor(this.themeColor)
|
|
|
|
|
- // .width(25)
|
|
|
|
|
- // .visibility(this.isHistory || this.isCanBack || this.isSearchMode ? Visibility.None : Visibility.Visible)
|
|
|
|
|
- // .animation({
|
|
|
|
|
- // duration: 666,
|
|
|
|
|
- // curve: 'ease-in-out' // 可选动画曲线
|
|
|
|
|
- // })
|
|
|
|
|
- // .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
|
|
|
|
|
- // .onClick(() => {
|
|
|
|
|
- // this.refreshCurrent()
|
|
|
|
|
- // })
|
|
|
|
|
|
|
+ Image($r("app.media.refresh"))
|
|
|
|
|
+ .fillColor(this.themeColor)
|
|
|
|
|
+ .width(25)
|
|
|
|
|
+ .visibility(this.isHistory || this.isCanBack || this.isSearchMode ? Visibility.None : Visibility.Visible)
|
|
|
|
|
+ .animation({
|
|
|
|
|
+ duration: 666,
|
|
|
|
|
+ curve: 'ease-in-out' // 可选动画曲线
|
|
|
|
|
+ })
|
|
|
|
|
+ .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ if (this.isFavMusic) {
|
|
|
|
|
+ this.getFavList(true)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(this.modeType == 0){
|
|
|
|
|
+ this.asyncCurrentPathData()
|
|
|
|
|
+ }else if(this.modeType ==1){
|
|
|
|
|
+ workerInstance.postMessage({ code: 2, data: this.context,data2:this.packName });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
Image($r("app.media.top_rank"))
|
|
Image($r("app.media.top_rank"))
|
|
|
.width(25)
|
|
.width(25)
|
|
@@ -4172,8 +4162,6 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
// Grid布局的开始
|
|
// Grid布局的开始
|
|
|
private dragRefOffSetX: number = 0;
|
|
private dragRefOffSetX: number = 0;
|
|
|
private dragRefOffSetY: number = 0;
|
|
private dragRefOffSetY: number = 0;
|
|
@@ -4794,25 +4782,6 @@ export struct LocalMusic {
|
|
|
this.pinchValue = 1;
|
|
this.pinchValue = 1;
|
|
|
this.scaleValue = 1;
|
|
this.scaleValue = 1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 扫描当前目录下的文件,不扫描子目录
|
|
|
|
|
- asyncCurrentPathOnlyFile(){
|
|
|
|
|
- if(this.modeType==0){
|
|
|
|
|
- const task = new taskpool.Task(scanCurrentDirectoryTask, getContext(this), this.currentPath,
|
|
|
|
|
- this.lockPath,PreferencesUtil.getStringSync('COVER_API',''));
|
|
|
|
|
- taskpool.execute(task, taskpool.Priority.HIGH).then(()=>{
|
|
|
|
|
- if(this.modeType==0){
|
|
|
|
|
- this.getSortedFiles(this.currentPath)
|
|
|
|
|
- }
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- this.isRefreshing = false;
|
|
|
|
|
- }, 100)
|
|
|
|
|
- }).catch((e:object)=>{
|
|
|
|
|
- console.info("task1 catch e: " + e);
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
getListView() {
|
|
getListView() {
|
|
|
|
|
|
|
@@ -10841,8 +10810,8 @@ export struct LocalMusic {
|
|
|
onClickBItem: async ()=>{
|
|
onClickBItem: async ()=>{
|
|
|
if(this.mIjkMediaPlayer){
|
|
if(this.mIjkMediaPlayer){
|
|
|
this.jumpBTime = await this.mIjkMediaPlayer.getCurrentPosition()
|
|
this.jumpBTime = await this.mIjkMediaPlayer.getCurrentPosition()
|
|
|
- if(this.jumpBTime<=this.jumpATime||stringForTime(this.jumpATime)==stringForTime(this.jumpBTime)){
|
|
|
|
|
- ToastUtil.showToast('设置B点时间不能小于或等于A点时间')
|
|
|
|
|
|
|
+ if(this.jumpBTime<=this.jumpATime){
|
|
|
|
|
+ ToastUtil.showToast('设置B点时间不能小于A点时间')
|
|
|
this.jumpBTime = 0
|
|
this.jumpBTime = 0
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -12079,15 +12048,17 @@ export struct LocalMusic {
|
|
|
|
|
|
|
|
// 发送播放状态变化事件给歌单详情页面
|
|
// 发送播放状态变化事件给歌单详情页面
|
|
|
try {
|
|
try {
|
|
|
- const eventPlaybackStatus: emitter.InnerEvent = { eventId: 2003 }
|
|
|
|
|
|
|
+ const eventPlaybackStatus: emitter.InnerEvent = { eventId: EventConstants.EVENT_PLAYBACK_STATUS }
|
|
|
|
|
+ const currentFilePath = this.currentSong?.filePath || ''
|
|
|
const eventData: emitter.EventData = {
|
|
const eventData: emitter.EventData = {
|
|
|
data: {
|
|
data: {
|
|
|
isPlaying: this.isPlaying,
|
|
isPlaying: this.isPlaying,
|
|
|
- curIndex: this.curIndex
|
|
|
|
|
|
|
+ curIndex: this.curIndex,
|
|
|
|
|
+ currentFilePath: currentFilePath
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
emitter.emit(eventPlaybackStatus, eventData)
|
|
emitter.emit(eventPlaybackStatus, eventData)
|
|
|
- Logger.info(`heanup 发送播放状态变化事件: isPlaying=${this.isPlaying}, curIndex=${this.curIndex}`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 发送播放状态变化事件: isPlaying=${this.isPlaying}, curIndex=${this.curIndex}, currentFilePath=${currentFilePath}`)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
Logger.error('heanup 发送播放状态变化事件失败: ' + error)
|
|
Logger.error('heanup 发送播放状态变化事件失败: ' + error)
|
|
|
}
|
|
}
|
|
@@ -13071,72 +13042,72 @@ export struct LocalMusic {
|
|
|
/**
|
|
/**
|
|
|
* 处理歌单播放请求
|
|
* 处理歌单播放请求
|
|
|
*/
|
|
*/
|
|
|
- private handlePlaylistPlayRequest(playlist: Playlist, songs: VideoItem[], startIndex: number) {
|
|
|
|
|
- try {
|
|
|
|
|
- // 1. 替换当前播放列表
|
|
|
|
|
- this.songList = songs
|
|
|
|
|
- this.sonDataSource.pushArrayData(songs)
|
|
|
|
|
-
|
|
|
|
|
- // 2. 设置当前播放索引
|
|
|
|
|
- this.curIndex = startIndex
|
|
|
|
|
-
|
|
|
|
|
- // 3. 播放指定歌曲
|
|
|
|
|
- if (songs[startIndex]) {
|
|
|
|
|
- this.doPlay(songs[startIndex], startIndex)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 4. 保存播放列表
|
|
|
|
|
- PreferencesUtil.putSync('LastMusicList', this.songList)
|
|
|
|
|
-
|
|
|
|
|
- console.info(`heanup 开始播放歌单: ${playlist.name}, 歌曲数量: ${songs.length}, 开始索引: ${startIndex}`)
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('heanup 处理歌单播放请求失败:', error)
|
|
|
|
|
- ToastUtil.showToast('播放失败')
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 处理简化的歌单播放请求
|
|
|
|
|
- */
|
|
|
|
|
- private handleSimplifiedPlaylistPlayRequest(playlistId: string, playlistName: string, songFilePaths: string[], startIndex: number) {
|
|
|
|
|
|
|
+ private handlePlaylistPlayRequest(playlistId: string, playlistName: string, songFilePaths: string[], startIndex: number) {
|
|
|
try {
|
|
try {
|
|
|
- Logger.info(`heanup 处理简化歌单播放请求: ${playlistName}, 歌曲数量: ${songFilePaths.length}, 开始索引: ${startIndex}`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 处理歌单播放请求: ${playlistName}, 歌曲数量: ${songFilePaths.length}, 开始索引: ${startIndex}`)
|
|
|
|
|
|
|
|
- // 从数据库重新加载这些歌曲
|
|
|
|
|
- const songs: VideoItem[] = []
|
|
|
|
|
|
|
+ // 从数据库重新加载这些歌曲,使用索引记录位置以保持顺序
|
|
|
|
|
+ const songMap: Map<number, VideoItem> = new Map()
|
|
|
let completedQueries = 0
|
|
let completedQueries = 0
|
|
|
|
|
|
|
|
Logger.info(`heanup 开始从数据库查询 ${songFilePaths.length} 首歌曲`)
|
|
Logger.info(`heanup 开始从数据库查询 ${songFilePaths.length} 首歌曲`)
|
|
|
|
|
|
|
|
- for (const filePath of songFilePaths) {
|
|
|
|
|
- Logger.info(`heanup 正在查询歌曲: ${filePath}`)
|
|
|
|
|
|
|
+ // 遍历所有文件路径,使用索引记录位置
|
|
|
|
|
+ for (let i = 0; i < songFilePaths.length; i++) {
|
|
|
|
|
+ const filePath = songFilePaths[i]
|
|
|
|
|
+ const index = i
|
|
|
|
|
+ Logger.info(`heanup 正在查询歌曲[${index}]: ${filePath}`)
|
|
|
|
|
+
|
|
|
// 使用已初始化的MediaTable实例从数据库查询歌曲信息
|
|
// 使用已初始化的MediaTable实例从数据库查询歌曲信息
|
|
|
const queryPromise = this.table.queryVideoByFilePath(filePath)
|
|
const queryPromise = this.table.queryVideoByFilePath(filePath)
|
|
|
- Logger.info(`heanup 创建了查询Promise,开始等待结果: ${filePath}`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 创建了查询Promise,开始等待结果[${index}]: ${filePath}`)
|
|
|
|
|
|
|
|
queryPromise.then((videoItem) => {
|
|
queryPromise.then((videoItem) => {
|
|
|
completedQueries++
|
|
completedQueries++
|
|
|
- Logger.info(`heanup 查询Promise返回结果: ${filePath}, 找到歌曲: ${videoItem ? videoItem.name : 'null'}`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 查询Promise返回结果[${index}]: ${filePath}, 找到歌曲: ${videoItem ? videoItem.name : 'null'}`)
|
|
|
|
|
|
|
|
if (videoItem) {
|
|
if (videoItem) {
|
|
|
- songs.push(videoItem)
|
|
|
|
|
- Logger.info(`heanup 从数据库找到歌曲: ${videoItem.name} (${completedQueries}/${songFilePaths.length})`)
|
|
|
|
|
|
|
+ // 使用索引作为key保存到Map中,保持原始顺序
|
|
|
|
|
+ songMap.set(index, videoItem)
|
|
|
|
|
+ Logger.info(`heanup 从数据库找到歌曲[${index}]: ${videoItem.name} (${completedQueries}/${songFilePaths.length})`)
|
|
|
} else {
|
|
} else {
|
|
|
- Logger.warn(`heanup 数据库中未找到歌曲: ${filePath} (${completedQueries}/${songFilePaths.length})`)
|
|
|
|
|
|
|
+ Logger.warn(`heanup 数据库中未找到歌曲[${index}]: ${filePath} (${completedQueries}/${songFilePaths.length})`)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 检查是否所有歌曲都已加载完成
|
|
// 检查是否所有歌曲都已加载完成
|
|
|
if (completedQueries === songFilePaths.length) {
|
|
if (completedQueries === songFilePaths.length) {
|
|
|
- Logger.info(`heanup 所有数据库查询完成,共找到 ${songs.length} 首歌曲`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 所有数据库查询完成,共找到 ${songMap.size} 首歌曲`)
|
|
|
|
|
+
|
|
|
|
|
+ // 按照索引顺序重建歌曲数组
|
|
|
|
|
+ const songs: VideoItem[] = []
|
|
|
|
|
+ for (let j = 0; j < songFilePaths.length; j++) {
|
|
|
|
|
+ const song = songMap.get(j)
|
|
|
|
|
+ if (song) {
|
|
|
|
|
+ songs.push(song)
|
|
|
|
|
+ Logger.info(`heanup 按顺序添加歌曲[${j}]: ${song.name}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Logger.info(`heanup 最终歌曲列表顺序: ${songs.map((s, idx) => `[${idx}]${s.name}`).join(', ')}`)
|
|
|
this.finishLoadingPlaylist(songs, startIndex, playlistName)
|
|
this.finishLoadingPlaylist(songs, startIndex, playlistName)
|
|
|
}
|
|
}
|
|
|
}).catch((error: Error) => {
|
|
}).catch((error: Error) => {
|
|
|
completedQueries++
|
|
completedQueries++
|
|
|
- Logger.error(`heanup 查询歌曲失败: ${filePath}, 错误: ${error.message} (${completedQueries}/${songFilePaths.length})`)
|
|
|
|
|
|
|
+ Logger.error(`heanup 查询歌曲失败[${index}]: ${filePath}, 错误: ${error.message} (${completedQueries}/${songFilePaths.length})`)
|
|
|
|
|
|
|
|
// 即使出错也要检查是否完成所有查询
|
|
// 即使出错也要检查是否完成所有查询
|
|
|
if (completedQueries === songFilePaths.length) {
|
|
if (completedQueries === songFilePaths.length) {
|
|
|
- Logger.info(`heanup 所有数据库查询完成(包含错误),共找到 ${songs.length} 首歌曲`)
|
|
|
|
|
|
|
+ Logger.info(`heanup 所有数据库查询完成(包含错误),共找到 ${songMap.size} 首歌曲`)
|
|
|
|
|
+
|
|
|
|
|
+ // 按照索引顺序重建歌曲数组
|
|
|
|
|
+ const songs: VideoItem[] = []
|
|
|
|
|
+ for (let j = 0; j < songFilePaths.length; j++) {
|
|
|
|
|
+ const song = songMap.get(j)
|
|
|
|
|
+ if (song) {
|
|
|
|
|
+ songs.push(song)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.finishLoadingPlaylist(songs, startIndex, playlistName)
|
|
this.finishLoadingPlaylist(songs, startIndex, playlistName)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -13156,40 +13127,21 @@ export struct LocalMusic {
|
|
|
ToastUtil.showToast('没有找到可播放的歌曲')
|
|
ToastUtil.showToast('没有找到可播放的歌曲')
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- Logger.info(`heanup 找到 ${songs.length} 首可播放的歌曲`)
|
|
|
|
|
-
|
|
|
|
|
- // 1. 替换当前播放列表并更新存储
|
|
|
|
|
- Logger.info(`heanup 更新前 - 当前播放列表长度: ${this.songList.length}`)
|
|
|
|
|
this.songList = songs
|
|
this.songList = songs
|
|
|
- // 确保存储也更新(@StorageLink会自动同步)
|
|
|
|
|
- Logger.info(`heanup 更新后 - 新播放列表长度: ${this.songList.length}`)
|
|
|
|
|
|
|
|
|
|
- // 2. 更新数据源
|
|
|
|
|
- Logger.info(`heanup 更新前 - 数据源长度: ${this.sonDataSource.totalCount()}`)
|
|
|
|
|
this.sonDataSource.pushArrayData(songs)
|
|
this.sonDataSource.pushArrayData(songs)
|
|
|
- Logger.info(`heanup 更新后 - 数据源长度: ${this.sonDataSource.totalCount()}`)
|
|
|
|
|
|
|
|
|
|
- // 3. 强制触发UI重新渲染
|
|
|
|
|
- Logger.info('heanup 触发UI重新渲染')
|
|
|
|
|
this.sonDataSource.notifyDataReload()
|
|
this.sonDataSource.notifyDataReload()
|
|
|
|
|
|
|
|
- // 4. 设置当前播放索引
|
|
|
|
|
this.curIndex = startIndex
|
|
this.curIndex = startIndex
|
|
|
|
|
|
|
|
- // 5. 播放指定歌曲
|
|
|
|
|
if (songs[startIndex]) {
|
|
if (songs[startIndex]) {
|
|
|
- Logger.info(`heanup 开始播放歌曲: ${songs[startIndex].name}, 索引: ${startIndex}`)
|
|
|
|
|
- Logger.info(`heanup 播放前 - 播放列表长度: ${this.songList.length}, 当前索引: ${this.curIndex}`)
|
|
|
|
|
// 确保当前播放的歌曲也更新到存储
|
|
// 确保当前播放的歌曲也更新到存储
|
|
|
AppStorage.setOrCreate('currentSong', songs[startIndex])
|
|
AppStorage.setOrCreate('currentSong', songs[startIndex])
|
|
|
// 设置isFromSonPlayList=true,避免doPlay方法重新从全局列表构建播放列表
|
|
// 设置isFromSonPlayList=true,避免doPlay方法重新从全局列表构建播放列表
|
|
|
- Logger.info(`heanup 调用doPlay,参数: 歌曲=${songs[startIndex].name}, 索引=${startIndex}, isFromSonPlayList=true`)
|
|
|
|
|
this.doPlay(songs[startIndex], startIndex, true)
|
|
this.doPlay(songs[startIndex], startIndex, true)
|
|
|
- Logger.info(`heanup doPlay调用完成`)
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 5. 保存播放列表
|
|
|
|
|
PreferencesUtil.putSync('LastMusicList', this.songList)
|
|
PreferencesUtil.putSync('LastMusicList', this.songList)
|
|
|
|
|
|
|
|
ToastUtil.showToast(`开始播放歌单: ${playlistName}`)
|
|
ToastUtil.showToast(`开始播放歌单: ${playlistName}`)
|
|
@@ -13244,6 +13196,7 @@ function customPopupBuilder(dataBu: BubbleBean) {
|
|
|
color: "#22FFFFFF"
|
|
color: "#22FFFFFF"
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
// Function to calculate a hash for the file list
|
|
// Function to calculate a hash for the file list
|
|
|
function simpleHash(fileList: string[]): string {
|
|
function simpleHash(fileList: string[]): string {
|
|
|
let hash = 0;
|
|
let hash = 0;
|
|
@@ -13344,51 +13297,4 @@ function getFileDirName(filePath: string,rootPath:string): string{
|
|
|
if(result.startsWith('.'))
|
|
if(result.startsWith('.'))
|
|
|
result = result.replace(/\./g, '')
|
|
result = result.replace(/\./g, '')
|
|
|
return result
|
|
return result
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-//只扫描当前目录下文件(不扫描子文件夹)的方法
|
|
|
|
|
-@Concurrent
|
|
|
|
|
-async function scanCurrentDirectoryTask(context: Context, dirPath: string, lockPath: string, cover_api: string) {
|
|
|
|
|
- const table: MediaTable = new MediaTable(context);
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- // 直接获取当前目录下的文件列表
|
|
|
|
|
- const files = FileUtil.listFileSync(dirPath);
|
|
|
|
|
-
|
|
|
|
|
- await Promise.all(files.map(async (file) => {
|
|
|
|
|
- const fPath = `${dirPath}/${file}`;
|
|
|
|
|
-
|
|
|
|
|
- // 跳过目录,只处理文件
|
|
|
|
|
- if (FileUtil.isDirectory(fPath)) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 跳过特定格式文件
|
|
|
|
|
- if (fPath.endsWith('.lrc') || fPath.endsWith('.srt')) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 检查是否为媒体文件
|
|
|
|
|
- if (Utility.isMeidaByExtension(fPath)) {
|
|
|
|
|
- let mType = CommonConstants.TYPE_LOCAL;
|
|
|
|
|
- if (fPath.includes(lockPath)) {
|
|
|
|
|
- mType = CommonConstants.TYPE_LOCK;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const mediaItem = await Utility.uriGetMusicAssetsFromFile(
|
|
|
|
|
- context, fPath, mType, true
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- table.insert(mediaItem, (id: number) => {
|
|
|
|
|
- // 插入回调函数
|
|
|
|
|
- }, cover_api);
|
|
|
|
|
- }
|
|
|
|
|
- }));
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error(' 扫描当前目录失败:', error);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+}
|